
<!DOCTYPE HTML>
<html lang="zh-hans" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>浅析 Vue Router 源码和动态路由权限分配 · 记录技术文档内容</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        <meta name="author" content="zhengyuliang">
        
        
    
    <link rel="stylesheet" href="../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-sectionx/sectionx.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-splitter/splitter.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-tbfed-pagefooter/footer.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-toggle-chapters/toggle.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-search-plus/search.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-donate/plugin.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-anchor-navigation-ex/style/plugin.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-expandable-chapters/expandable-chapters.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-chapter-fold/chapter-fold.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-theme-comscore/test.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="父组件监听到子组件的生命周期.html" />
    
    
    <link rel="prev" href="从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境.html" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="输入并搜索" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        <li class="header">CSS</li>
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    Introduction
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="../CSS/18种CSS命名和书写规范.html">
            
                <a href="../CSS/18种CSS命名和书写规范.html">
            
                    
                    18种CSS命名和书写规范
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3" data-path="../CSS/灵活运用CSS开发技巧.html">
            
                <a href="../CSS/灵活运用CSS开发技巧.html">
            
                    
                    灵活运用CSS开发技巧
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4" data-path="../CSS/自适应 flex grid.html">
            
                <a href="../CSS/自适应 flex grid.html">
            
                    
                    自适应 Flex Grid
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">HTML</li>
        
        
    
        <li class="chapter " data-level="2.1" data-path="../HTML/浏览器里的本地数据库：IndexedDB.html">
            
                <a href="../HTML/浏览器里的本地数据库：IndexedDB.html">
            
                    
                    浏览器里的本地数据库：IndexedDB
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Vue</li>
        
        
    
        <li class="chapter " data-level="3.1" data-path="7个有用的Vue开发技巧.html">
            
                <a href="7个有用的Vue开发技巧.html">
            
                    
                    7个有用的Vue开发技巧
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.2" data-path="Vue this.$router.push、replace、go的区别.html">
            
                <a href="Vue this.$router.push、replace、go的区别.html">
            
                    
                    Vue This.$Router.Push、Replace、Go的区别
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.3" data-path="Vue 的父组件和子组件生命周期钩子函数执行顺序？.html">
            
                <a href="Vue 的父组件和子组件生命周期钩子函数执行顺序？.html">
            
                    
                    Vue 的父组件和子组件生命周期钩子函数执行顺序？
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.4" data-path="Vue.set和this.$set应用的场景.html">
            
                <a href="Vue.set和this.$set应用的场景.html">
            
                    
                    Vue.Set和This.$Set应用的场景
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.5" data-path="vue高级技巧.html">
            
                <a href="vue高级技巧.html">
            
                    
                    Vue高级技巧
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.6" data-path="从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境.html">
            
                <a href="从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境.html">
            
                    
                    从 0 开始手把手带你搭建一套规范的 Vue3.X 项目工程环境
            
                </a>
            

            
        </li>
    
        <li class="chapter active" data-level="3.7" data-path="浅析 vue-router 源码和动态路由权限分配.html">
            
                <a href="浅析 vue-router 源码和动态路由权限分配.html">
            
                    
                    浅析 Vue Router 源码和动态路由权限分配
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.8" data-path="父组件监听到子组件的生命周期.html">
            
                <a href="父组件监听到子组件的生命周期.html">
            
                    
                    父组件监听到子组件的生命周期
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.9" data-path="理解Vue.mixin，利用Vue.mixin正确的偷懒.html">
            
                <a href="理解Vue.mixin，利用Vue.mixin正确的偷懒.html">
            
                    
                    理解Vue.Mixin，利用Vue.Mixin正确的偷懒
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">JavaScript</li>
        
        
    
        <li class="chapter " data-level="4.1" data-path="../javaScript/5个技巧让你更好的编写 JavaScript(ES6">
            
                <span>
            
                    
                    5个技巧让你更好的编写 JavaScript(ES6) 中条件语句
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2" data-path="../javaScript/5种常见函数的写法和调用方式.html">
            
                <a href="../javaScript/5种常见函数的写法和调用方式.html">
            
                    
                    5种常见函数的写法和调用方式
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.3" data-path="../javaScript/7道javascript题，让你理解基本的javascript.html">
            
                <a href="../javaScript/7道javascript题，让你理解基本的javascript.html">
            
                    
                    7道Javascript题，让你理解基本的Javascript
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.4" data-path="../javaScript/Array.from(">
            
                <span>
            
                    
                    Array.From() 五个超好用的用途
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.5" data-path="../javaScript/ES6汇总资料.html">
            
                <a href="../javaScript/ES6汇总资料.html">
            
                    
                    ES6汇总资料
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.6" data-path="../javaScript/JS开发必须知道的41个技巧.html">
            
                <a href="../javaScript/JS开发必须知道的41个技巧.html">
            
                    
                    JS开发必须知道的41个技巧
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.7" data-path="../javaScript/JavaScript之防抖Debounce和节流Throttle.html">
            
                <a href="../javaScript/JavaScript之防抖Debounce和节流Throttle.html">
            
                    
                    JavaScript之防抖Debounce和节流Throttle
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.8" data-path="../javaScript/JavaScript数组求并集，交集和差集.html">
            
                <a href="../javaScript/JavaScript数组求并集，交集和差集.html">
            
                    
                    JavaScript数组求并集，交集和差集
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.9" data-path="../javaScript/JavaScript的优雅写法.html">
            
                <a href="../javaScript/JavaScript的优雅写法.html">
            
                    
                    JavaScript的优雅写法
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.10" data-path="../javaScript/axios知识点.html">
            
                <a href="../javaScript/axios知识点.html">
            
                    
                    Axios知识点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.11" data-path="../javaScript/javascript核心知识.html">
            
                <a href="../javaScript/javascript核心知识.html">
            
                    
                    Javascript核心知识
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.12" data-path="../javaScript/this、apply、call、bind.html">
            
                <a href="../javaScript/this、apply、call、bind.html">
            
                    
                    This、Apply、Call、Bind
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.13" data-path="../javaScript/前端js常用的60余种工具方法.html">
            
                <a href="../javaScript/前端js常用的60余种工具方法.html">
            
                    
                    前端Js常用的60余种工具方法
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.14" data-path="../javaScript/前端异常的捕获与处理.html">
            
                <a href="../javaScript/前端异常的捕获与处理.html">
            
                    
                    前端异常的捕获与处理
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.15" data-path="../javaScript/在 JavaScript 中交换值的 10 种方法.html">
            
                <a href="../javaScript/在 JavaScript 中交换值的 10 种方法.html">
            
                    
                    在 JavaScript 中交换值的 10 种方法
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.16" data-path="../javaScript/常用的前端JavaScript方法封装.html">
            
                <a href="../javaScript/常用的前端JavaScript方法封装.html">
            
                    
                    常用的前端JavaScript方法封装
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.17" data-path="../javaScript/异步神器Async-await介绍与填坑.html">
            
                <a href="../javaScript/异步神器Async-await介绍与填坑.html">
            
                    
                    异步神器Async Await介绍与填坑
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.18" data-path="../javaScript/灵活运用JS开发技巧.html">
            
                <a href="../javaScript/灵活运用JS开发技巧.html">
            
                    
                    灵活运用JS开发技巧
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.19" data-path="../javaScript/编写高质量可维护的代码：一目了然的注释.html">
            
                <a href="../javaScript/编写高质量可维护的代码：一目了然的注释.html">
            
                    
                    编写高质量可维护的代码：一目了然的注释
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.20" data-path="../javaScript/编写高质量可维护的代码：优化逻辑判断.html">
            
                <a href="../javaScript/编写高质量可维护的代码：优化逻辑判断.html">
            
                    
                    编写高质量可维护的代码：优化逻辑判断
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.21" data-path="../javaScript/编写高质量可维护的代码：优雅命名.html">
            
                <a href="../javaScript/编写高质量可维护的代码：优雅命名.html">
            
                    
                    编写高质量可维护的代码：优雅命名
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.22" data-path="../javaScript/编写高质量可维护的代码：数据建模.html">
            
                <a href="../javaScript/编写高质量可维护的代码：数据建模.html">
            
                    
                    编写高质量可维护的代码：数据建模
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Life Exp</li>
        
        
    
        <li class="chapter " data-level="5.1" data-path="../life_exp/告别平庸的15个小方法.html">
            
                <a href="../life_exp/告别平庸的15个小方法.html">
            
                    
                    告别平庸的15个小方法
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="5.2" data-path="../life_exp/日志记录.html">
            
                <a href="../life_exp/日志记录.html">
            
                    
                    日志记录
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="5.3" data-path="../life_exp/程序员的发展方向.html">
            
                <a href="../life_exp/程序员的发展方向.html">
            
                    
                    程序员的发展方向
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="5.4" data-path="../message/">
            
                <a href="../message/">
            
                    
                    Message
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Technology</li>
        
        
    
        <li class="chapter " data-level="6.1" data-path="../technology/WebSocket.html">
            
                <a href="../technology/WebSocket.html">
            
                    
                    WebSocket
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="6.2" data-path="../technology/npm常用命令大全.html">
            
                <a href="../technology/npm常用命令大全.html">
            
                    
                    Npm常用命令大全
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="6.3" data-path="../technology/智能照明项目说明.html">
            
                <a href="../technology/智能照明项目说明.html">
            
                    
                    智能照明项目说明
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="6.4" data-path="../technology/规范化git的提交信息.html">
            
                <a href="../technology/规范化git的提交信息.html">
            
                    
                    规范化Git的提交信息
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Tutorial</li>
        
        
    
        <li class="chapter " data-level="7.1" data-path="../tutorial/Esmap地图详解.html">
            
                <a href="../tutorial/Esmap地图详解.html">
            
                    
                    Esmap地图详解
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="7.2" data-path="../tutorial/npm镜像切换.html">
            
                <a href="../tutorial/npm镜像切换.html">
            
                    
                    Npm镜像切换
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="7.3" data-path="../tutorial/发布npm的教程.html">
            
                <a href="../tutorial/发布npm的教程.html">
            
                    
                    发布Npm的教程
            
                </a>
            

            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            本书使用 GitBook 发布
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >浅析 Vue Router 源码和动态路由权限分配</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div class="search-plus" id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <html><head></head><body><div id="anchor-navigation-ex-navbar"><i class="fa fa-navicon"></i><ul><li><span class="title-icon "></span><a href="#&#x6D45;&#x6790;-vue-router-&#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;"><b>1. </b>&#x6D45;&#x6790; vue-router &#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;</a></li><ul><li><span class="title-icon "></span><a href="#&#x80CC;&#x666F;"><b>1.1. </b>&#x80CC;&#x666F;</a></li><li><span class="title-icon "></span><a href="#vue-router-&#x6E90;&#x7801;&#x5206;&#x6790;"><b>1.2. </b>vue-router &#x6E90;&#x7801;&#x5206;&#x6790;</a></li><ul><li><span class="title-icon "></span><a href="#&#x524D;&#x7F6E;&#x77E5;&#x8BC6;-flow-&#x8BED;&#x6CD5;"><b>1.2.1. </b>&#x524D;&#x7F6E;&#x77E5;&#x8BC6;: flow &#x8BED;&#x6CD5;</a></li><li><span class="title-icon "></span><a href="#&#x6CE8;&#x518C;"><b>1.2.2. </b>&#x6CE8;&#x518C;</a></li><li><span class="title-icon "></span><a href="#vuerouter"><b>1.2.3. </b>VueRouter</a></li><li><span class="title-icon "></span><a href="#matcher"><b>1.2.4. </b>Matcher</a></li><li><span class="title-icon "></span><a href="#&#x8DEF;&#x7531;&#x6A21;&#x5F0F;"><b>1.2.5. </b>&#x8DEF;&#x7531;&#x6A21;&#x5F0F;</a></li><li><span class="title-icon "></span><a href="#&#x8DEF;&#x7531;&#x5207;&#x6362;"><b>1.2.6. </b>&#x8DEF;&#x7531;&#x5207;&#x6362;</a></li><li><span class="title-icon "></span><a href="#router-view--router-link"><b>1.2.7. </b>router-view &amp; router-link</a></li></ul><li><span class="title-icon "></span><a href="#&#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x539F;&#x7406;&#x5206;&#x6790;"><b>1.3. </b>&#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x539F;&#x7406;&#x5206;&#x6790;</a></li><ul><li><span class="title-icon "></span><a href="#&#x767B;&#x5F55;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5168;&#x8FC7;&#x7A0B;"><b>1.3.1. </b>&#x767B;&#x5F55;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5168;&#x8FC7;&#x7A0B;</a></li><li><span class="title-icon "></span><a href="#&#x7ED3;&#x5408;&#x6846;&#x67B6;&#x6E90;&#x7801;&#x5206;&#x6790;"><b>1.3.2. </b>&#x7ED3;&#x5408;&#x6846;&#x67B6;&#x6E90;&#x7801;&#x5206;&#x6790;</a></li></ul><li><span class="title-icon "></span><a href="#&#x603B;&#x7ED3;"><b>1.4. </b>&#x603B;&#x7ED3;</a></li></ul></ul></div><a href="#&#x6D45;&#x6790;-vue-router-&#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a><h1 id="&#x6D45;&#x6790;-vue-router-&#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;"><a name="&#x6D45;&#x6790;-vue-router-&#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;" class="anchor-navigation-ex-anchor" href="#&#x6D45;&#x6790;-vue-router-&#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;"><i class="fa fa-link" aria-hidden="true"></i></a>1. &#x6D45;&#x6790; vue-router &#x6E90;&#x7801;&#x548C;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x5206;&#x914D;</h1>
<p>[TOC]</p>
<h2 id="&#x80CC;&#x666F;"><a name="&#x80CC;&#x666F;" class="anchor-navigation-ex-anchor" href="#&#x80CC;&#x666F;"><i class="fa fa-link" aria-hidden="true"></i></a>1.1. &#x80CC;&#x666F;</h2>
<p>&#x4E0A;&#x6708;&#x7ACB;&#x8FC7;&#x4E00;&#x4E2A; flag&#xFF0C;&#x770B;&#x5B8C; <code>vue-router</code> &#x7684;&#x6E90;&#x7801;&#xFF0C;&#x53EF;&#x5230;&#x540E;&#x9762;&#x9010;&#x6E10;&#x53D1;&#x73B0; <code>vue-router</code> &#x7684;&#x6E90;&#x7801;&#x5E76;&#x4E0D;&#x662F;&#x50CF;&#x5F88;&#x591A;&#x603B;&#x7ED3;&#x7684;&#x6587;&#x7AE0;&#x90A3;&#x4E48;&#x5BB9;&#x6613;&#x7406;&#x89E3;&#xFF0C;&#x9605;&#x8BFB;&#x8FC7;&#x4F60;&#x5C31;&#x4F1A;&#x53D1;&#x73B0;&#x91CC;&#x9762;&#x7684;&#x5F88;&#x591A;&#x5730;&#x65B9;&#x90FD;&#x4F1A;&#x6709;&#x591A;&#x5C42;&#x7684;&#x51FD;&#x6570;&#x8C03;&#x7528;&#x5173;&#x7CFB;&#xFF0C;&#x8FD8;&#x6709;&#x5927;&#x91CF;&#x7684; this &#x6307;&#x5411;&#x95EE;&#x9898;&#xFF0C;&#x800C;&#x4E14;&#x4F1A;&#x6709;&#x5F88;&#x591A;&#x8F85;&#x52A9;&#x51FD;&#x6570;&#x9700;&#x8981;&#x53BB;&#x7406;&#x89E3;&#x3002;&#x4F46;&#x8FD8;&#x662F;&#x575A;&#x6301;&#x5543;&#x4E0B;&#x6765;&#x4E86;(&#x5F53;&#x7136;&#x8FD8;&#x6CA1;&#x770B;&#x5B8C;&#xFF0C;&#x5185;&#x5BB9;&#x662F;&#x771F;&#x7684;&#x591A;)&#xFF0C;&#x4E0B;&#x9762;&#x662F;&#x6211;&#x5728;&#x653F;&#x91C7;&#x4E91;(&#x5B9E;&#x4E60;)&#x5DE5;&#x4F5C;&#x95F2;&#x6687;&#x65F6;&#x95F4;&#x9605;&#x8BFB;&#x6E90;&#x7801;&#x7684;&#x4E00;&#x4E9B;&#x611F;&#x609F;&#x548C;&#x603B;&#x7ED3;&#xFF0C;&#x5E76;&#x5E26;&#x5206;&#x6790;&#x4E86;&#x5927;&#x4E09;&#x65F6;&#x671F;&#x4F7F;&#x7528;&#x7684; <a href="https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/#&#x529F;&#x80FD;" target="_blank">vue-element-admin</a> &#x8FD9;&#x4E2A; vuer &#x65E0;&#x6240;&#x4E0D;&#x77E5;&#x7684;&#x540E;&#x53F0;&#x6846;&#x67B6;&#x7684;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x63A7;&#x5236;&#x539F;&#x7406;&#x3002;&#x987A;&#x4FBF;&#x9644;&#x5E26;&#x672C;&#x6587;&#x5B9E;&#x8DF5; demo &#x5730;&#x5740;: &#x57FA;&#x4E8E;&#x540E;&#x53F0;&#x6846;&#x67B6;&#x5F00;&#x53D1;&#x7684; <a href="https://github.com/251205668/student-admin-template" target="_blank">&#x5B66;&#x751F;&#x7BA1;&#x7406;&#x7CFB;&#x7EDF;</a>&#x3002;</p>
<h2 id="vue-router-&#x6E90;&#x7801;&#x5206;&#x6790;"><a name="vue-router-&#x6E90;&#x7801;&#x5206;&#x6790;" class="anchor-navigation-ex-anchor" href="#vue-router-&#x6E90;&#x7801;&#x5206;&#x6790;"><i class="fa fa-link" aria-hidden="true"></i></a>1.2. vue-router &#x6E90;&#x7801;&#x5206;&#x6790;</h2>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_141447372_0.png" alt="60"></p>
<p>&#x9996;&#x5148;&#x9605;&#x8BFB;&#x6E90;&#x7801;&#x4E4B;&#x524D;&#x6700;&#x597D;&#x662F;&#x5C06; <code>Vue</code> &#x548C; <code>vue-router</code> &#x7684;&#x6E90;&#x7801;&#x514B;&#x9686;&#x4E0B;&#x6765;&#xFF0C;&#x7136;&#x540E;&#x7B2C;&#x4E00;&#x904D;&#x9605;&#x8BFB;&#x5EFA;&#x8BAE;&#x5148;&#x8DDF;&#x7740; <a href="https://router.vuejs.org/zh/" target="_blank">&#x5B98;&#x65B9;&#x6587;&#x6863;</a> &#x5148;&#x8D70;&#x4E00;&#x904D;&#x57FA;&#x7840;&#x7528;&#x6CD5;&#xFF0C;&#x7136;&#x540E;&#x7B2C;&#x4E8C;&#x904D;&#x5F00;&#x59CB;&#x9605;&#x8BFB;&#x6E90;&#x7801;&#xFF0C;&#x5148;&#x7406;&#x6E05;&#x695A;&#x5404;&#x5C42;&#x7EA7;&#x76EE;&#x5F55;&#x7684;&#x4F5C;&#x7528;&#x548C;&#x62BD;&#x51FA;&#x4E00;&#x4E9B;&#x6838;&#x5FC3;&#x7684;&#x6587;&#x4EF6;&#x51FA;&#x6765;&#xFF0C;&#x8FC7;&#x4E00;&#x904D;&#x4EE3;&#x7801;&#x7684;&#x540C;&#x65F6;&#x5199;&#x4E2A;&#x5C0F;&#x7684; demo &#x8FB9;&#x770B;&#x8FB9;&#x6253;&#x65AD;&#x70B9;&#x8C03;&#x8BD5;&#xFF0C;&#x770B;&#x4E0D;&#x61C2;&#x6CA1;&#x5173;&#x7CFB;&#xFF0C;&#x53EF;&#x4EE5;&#x8FB9;&#x770B;&#x8FB9;&#x53C2;&#x8003;&#x4E00;&#x4E9B;&#x603B;&#x7ED3;&#x7684;&#x6BD4;&#x8F83;&#x597D;&#x7684;&#x6587;&#x7AE0;&#xFF0C;&#x6700;&#x540E;&#x5C06;&#x6BD4;&#x8F83;&#x91CD;&#x8981;&#x7684;&#x539F;&#x7406;&#x8FC7;&#x7A0B;&#x6839;&#x636E;&#x81EA;&#x5DF1;&#x7684;&#x7406;&#x89E3;&#x6574;&#x7406;&#x51FA;&#x6765;&#xFF0C;&#x7136;&#x540E;&#x753B;&#x4E00;&#x753B;&#x76F8;&#x5173;&#x7684;&#x77E5;&#x8BC6;&#x8111;&#x56FE;&#x52A0;&#x6DF1;&#x5370;&#x8C61;&#x3002;</p>
<h3 id="&#x524D;&#x7F6E;&#x77E5;&#x8BC6;-flow-&#x8BED;&#x6CD5;"><a name="&#x524D;&#x7F6E;&#x77E5;&#x8BC6;-flow-&#x8BED;&#x6CD5;" class="anchor-navigation-ex-anchor" href="#&#x524D;&#x7F6E;&#x77E5;&#x8BC6;-flow-&#x8BED;&#x6CD5;"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.1. &#x524D;&#x7F6E;&#x77E5;&#x8BC6;: flow &#x8BED;&#x6CD5;</h3>
<p>JS &#x5728;&#x7F16;&#x8BD1;&#x8FC7;&#x7A0B;&#x4E2D;&#x53EF;&#x80FD;&#x770B;&#x4E0D;&#x51FA;&#x4E00;&#x4E9B;&#x9690;&#x853D;&#x7684;&#x9519;&#x8BEF;&#xFF0C;&#x4F46;&#x5728;&#x8FD0;&#x884C;&#x8FC7;&#x7A0B;&#x4E2D;&#x4F1A;&#x62A5;&#x5404;&#x79CD;&#x5404;&#x6837;&#x7684; bug&#x3002;<a href="https://flow.org/en/docs/getting-started/" target="_blank">flow</a> &#x7684;&#x4F5C;&#x7528;&#x5C31;&#x662F;&#x7F16;&#x8BD1;&#x671F;&#x95F4;&#x8FDB;&#x884C;&#x9759;&#x6001;&#x7C7B;&#x578B;&#x68C0;&#x67E5;&#xFF0C;&#x5C3D;&#x65E9;&#x53D1;&#x73B0;&#x9519;&#x8BEF;&#xFF0C;&#x629B;&#x51FA;&#x5F02;&#x5E38;&#x3002;</p>
<p><code>Vue</code>&#x3001;<code>Vue-router</code> &#x7B49;&#x5927;&#x578B;&#x9879;&#x76EE;&#x5F80;&#x5F80;&#x9700;&#x8981;&#x8FD9;&#x79CD;&#x5DE5;&#x5177;&#x53BB;&#x505A;&#x9759;&#x6001;&#x7C7B;&#x578B;&#x68C0;&#x67E5;&#x4EE5;&#x4FDD;&#x8BC1;&#x4EE3;&#x7801;&#x7684;&#x53EF;&#x7EF4;&#x62A4;&#x6027;&#x548C;&#x53EF;&#x9760;&#x6027;&#x3002;&#x672C;&#x6587;&#x6240;&#x5206;&#x6790;&#x7684; <code>vue-router</code> &#x6E90;&#x7801;&#x4E2D;&#x5C31;&#x5927;&#x91CF;&#x7684;&#x91C7;&#x7528;&#x4E86; flow &#x53BB;&#x7F16;&#x5199;&#x51FD;&#x6570;&#xFF0C;&#x6240;&#x4EE5;&#x5B66;&#x4E60; flow &#x7684;&#x8BED;&#x6CD5;&#x662F;&#x6709;&#x5FC5;&#x8981;&#x7684;&#x3002;</p>
<p>&#x9996;&#x5148;&#x5B89;&#x88C5; flow &#x73AF;&#x5883;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x73AF;&#x5883;</p>
<pre><code class="lang-shell">npm install flow-bin -g
flow init
</code></pre>
<p>&#x5728; <code>index.js</code> &#x4E2D;&#x8F93;&#x5165;&#x8FD9;&#x4E00;&#x6BB5;&#x62A5;&#x9519;&#x7684;&#x4EE3;&#x7801;</p>
<pre><code class="lang-js"><span class="hljs-comment">/*@flow*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">x: string, y: number</span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">return</span> x + y
}
add(<span class="hljs-number">2</span>, <span class="hljs-number">11</span>)
</code></pre>
<p>&#x5728;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x5165; flow &#xFF0C;&#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x4E0D;&#x51FA;&#x610F;&#x5916;&#x5C31;&#x4F1A;&#x629B;&#x51FA;&#x5F02;&#x5E38;&#x63D0;&#x793A;&#xFF0C;&#x8FD9;&#x5C31;&#x662F;&#x7B80;&#x5355;&#x7684; flow &#x4F7F;&#x7528;&#x65B9;&#x6CD5;&#x3002;</p>
<h3 id="&#x6CE8;&#x518C;"><a name="&#x6CE8;&#x518C;" class="anchor-navigation-ex-anchor" href="#&#x6CE8;&#x518C;"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.2. &#x6CE8;&#x518C;</h3>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_143446918_0.png" alt="63"></p>
<p>&#x6211;&#x4EEC;&#x5E73;&#x65F6;&#x5728;&#x4F7F;&#x7528; <code>vue-router</code> &#x7684;&#x65F6;&#x5019;&#x901A;&#x5E38;&#x9700;&#x8981;&#x5728; <code>main.js</code> &#x4E2D;&#x521D;&#x59CB;&#x5316; <code>Vue</code> &#x5B9E;&#x4F8B;&#x65F6;&#x5C06; <code>vue-router</code> &#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#x5F53;&#x505A;&#x53C2;&#x6570;&#x4F20;&#x5165;</p>
<p>&#x4F8B;&#x5982;:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Router <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;vue-router&apos;</span>
Vue.use(Router)
<span class="hljs-keyword">const</span> routes = [
   {
    <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;/student&apos;</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">&apos;student&apos;</span>,
    <span class="hljs-attr">component</span>: Layout,
    <span class="hljs-attr">meta</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">&apos;&#x5B66;&#x751F;&#x4FE1;&#x606F;&#x67E5;&#x8BE2;&apos;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&apos;documentation&apos;</span>, <span class="hljs-attr">roles</span>: [<span class="hljs-string">&apos;student&apos;</span>] },
    <span class="hljs-attr">children</span>: [
      {
        <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;info&apos;</span>,
        <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">&apos;@/views/student/info&apos;</span>),
        <span class="hljs-attr">name</span>: <span class="hljs-string">&apos;studentInfo&apos;</span>,
        <span class="hljs-attr">meta</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">&apos;&#x4FE1;&#x606F;&#x67E5;&#x8BE2;&apos;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&apos;form&apos;</span> }
      },
      {
        <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;score&apos;</span>,
        <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">&apos;@/views/student/score&apos;</span>),
        <span class="hljs-attr">name</span>: <span class="hljs-string">&apos;studentScore&apos;</span>,
        <span class="hljs-attr">meta</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">&apos;&#x6210;&#x7EE9;&#x67E5;&#x8BE2;&apos;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&apos;score&apos;</span> }
      }
    ]
  }
  ...
];
<span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> Router({
  <span class="hljs-attr">mode</span>: <span class="hljs-string">&quot;history&quot;</span>,
  <span class="hljs-attr">linkActiveClass</span>: <span class="hljs-string">&quot;active&quot;</span>,
  <span class="hljs-attr">base</span>: process.env.BASE_URL,
  routes
});
<span class="hljs-keyword">new</span> Vue({
    router,
    store,
    <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =&gt;</span> h(App)
}).$mount(<span class="hljs-string">&quot;#app&quot;</span>);
</code></pre>
<h4 id="vueuse"><a name="vueuse" class="anchor-navigation-ex-anchor" href="#vueuse"><i class="fa fa-link" aria-hidden="true"></i></a>Vue.use</h4>
<p>&#x90A3;&#x4E48; <code>Vue.use(Router)</code> &#x53C8;&#x5728;&#x505A;&#x4EC0;&#x4E48;&#x4E8B;&#x60C5;&#x5462;</p>
<p>&#x95EE;&#x9898;&#x5B9A;&#x4F4D;&#x5230; <code>Vue</code> &#x6E90;&#x7801;&#x4E2D;&#x7684; <code>src/core/global-api/use.js</code> <a href="https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initUse</span> (<span class="hljs-params">Vue: GlobalAPI</span>) </span>{
  Vue.use = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">plugin: Function | Object</span>) </span>{
    <span class="hljs-comment">// &#x62FF;&#x5230; installPlugins </span>
    <span class="hljs-keyword">const</span> installedPlugins = (<span class="hljs-keyword">this</span>._installedPlugins || (<span class="hljs-keyword">this</span>._installedPlugins = []))
    <span class="hljs-comment">// &#x4FDD;&#x8BC1;&#x4E0D;&#x4F1A;&#x91CD;&#x590D;&#x6CE8;&#x518C;</span>
    <span class="hljs-keyword">if</span> (installedPlugins.indexOf(plugin) &gt; <span class="hljs-number">-1</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>
    }
    <span class="hljs-comment">// &#x83B7;&#x53D6;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570; plugins &#x4EE5;&#x5916;&#x7684;&#x53C2;&#x6570;</span>
    <span class="hljs-keyword">const</span> args = toArray(<span class="hljs-built_in">arguments</span>, <span class="hljs-number">1</span>)
    <span class="hljs-comment">// &#x5C06; Vue &#x5B9E;&#x4F8B;&#x6DFB;&#x52A0;&#x5230;&#x53C2;&#x6570;</span>
    args.unshift(<span class="hljs-keyword">this</span>)
    <span class="hljs-comment">// &#x6267;&#x884C; plugin &#x7684; install &#x65B9;&#x6CD5; &#x6BCF;&#x4E2A; insatll &#x65B9;&#x6CD5;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x90FD;&#x4F1A;&#x53D8;&#x6210; Vue&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x989D;&#x5916;&#x5F15;&#x5165;</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> plugin.install === <span class="hljs-string">&apos;function&apos;</span>) {
      plugin.install.apply(plugin, args)
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> plugin === <span class="hljs-string">&apos;function&apos;</span>) {
      plugin.apply(<span class="hljs-literal">null</span>, args)
    }
    <span class="hljs-comment">// &#x6700;&#x540E;&#x7528; installPlugins &#x4FDD;&#x5B58; </span>
    installedPlugins.push(plugin)
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>
  }
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230; <code>Vue</code> &#x7684; <code>use</code> &#x65B9;&#x6CD5;&#x4F1A;&#x63A5;&#x53D7;&#x4E00;&#x4E2A; <code>plugin</code> &#x53C2;&#x6570;&#xFF0C;&#x7136;&#x540E;&#x4F7F;&#x7528; <code>installPlugins</code> &#x6570;&#x7EC4;&#x4FDD;&#x5B58;&#x5DF2;&#x7ECF;&#x6CE8;&#x518C;&#x8FC7;&#x7684; <code>plugin</code> &#x3002; &#x9996;&#x5148;&#x4FDD;&#x8BC1; <code>plugin</code> &#x4E0D;&#x88AB;&#x91CD;&#x590D;&#x6CE8;&#x518C;&#xFF0C;&#x7136;&#x540E;&#x5C06; <code>Vue</code> &#x4ECE;&#x51FD;&#x6570;&#x53C2;&#x6570;&#x4E2D;&#x53D6;&#x51FA;&#xFF0C;&#x5C06;&#x6574;&#x4E2A; <code>Vue</code> &#x4F5C;&#x4E3A; <code>plugin</code> &#x7684;<code>install</code> &#x65B9;&#x6CD5;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x8FD9;&#x6837;&#x505A;&#x7684;&#x597D;&#x5904;&#x5C31;&#x662F;&#x4E0D;&#x9700;&#x8981;&#x9EBB;&#x70E6;&#x7684;&#x53E6;&#x5916;&#x5F15;&#x5165; <code>Vue</code>,&#x4FBF;&#x4E8E;&#x64CD;&#x4F5C;&#x3002; &#x63A5;&#x7740;&#x5C31;&#x53BB;&#x5224;&#x65AD; <code>plugin</code> &#x4E0A;&#x662F;&#x5426;&#x5B58;&#x5728; <code>install</code> &#x65B9;&#x6CD5;&#x3002;&#x5B58;&#x5728;&#x5219;&#x5C06;&#x8D4B;&#x503C;&#x540E;&#x7684;&#x53C2;&#x6570;&#x4F20;&#x5165;&#x6267;&#x884C; &#xFF0C;&#x6700;&#x540E;&#x5C06;&#x6240;&#x6709;&#x7684;&#x5B58;&#x5728; <code>install</code> &#x65B9;&#x6CD5;&#x7684; <code>plugin</code> &#x4EA4;&#x7ED9; <code>installPlugins</code>&#x7EF4;&#x62A4;&#x3002;</p>
<h4 id="install"><a name="install" class="anchor-navigation-ex-anchor" href="#install"><i class="fa fa-link" aria-hidden="true"></i></a>install</h4>
<p>&#x4E86;&#x89E3;&#x6E05;&#x695A; <code>Vue.use</code> &#x7684;&#x7ED3;&#x6784;&#x4E4B;&#x540E;&#xFF0C;&#x53EF;&#x4EE5;&#x5F97;&#x51FA; <code>Vue</code> &#x6CE8;&#x518C;&#x63D2;&#x4EF6;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x5728;&#x6267;&#x884C;&#x63D2;&#x4EF6;&#x7684; <code>install</code> &#x65B9;&#x6CD5;&#xFF0C;&#x53C2;&#x6570;&#x7684;&#x7B2C;&#x4E00;&#x9879;&#x5C31;&#x662F; <code>Vue</code>,&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x5C06;&#x4EE3;&#x7801;&#x5B9A;&#x4F4D;&#x5230; <code>vue-router</code> &#x6E90;&#x7801;&#x4E2D;&#x7684; <code>src/install.js</code> <a href="https://github.com/vuejs/vue-router/blob/dev/src/install.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// &#x4FDD;&#x5B58; Vue &#x7684;&#x5C40;&#x90E8;&#x53D8;&#x91CF;</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> _Vue
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">install</span> (<span class="hljs-params">Vue</span>) </span>{
  <span class="hljs-comment">// &#x5982;&#x679C;&#x5DF2;&#x5B89;&#x88C5;</span>
  <span class="hljs-keyword">if</span> (install.installed &amp;&amp; _Vue === Vue) <span class="hljs-keyword">return</span>
  install.installed = <span class="hljs-literal">true</span>
 <span class="hljs-comment">// &#x5C40;&#x90E8;&#x53D8;&#x91CF;&#x4FDD;&#x7559;&#x4F20;&#x5165;&#x7684; Vue</span>
  _Vue = Vue
  <span class="hljs-keyword">const</span> isDef = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v !== <span class="hljs-literal">undefined</span>
  <span class="hljs-keyword">const</span> registerInstance = <span class="hljs-function">(<span class="hljs-params">vm, callVal</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> i = vm.$options._parentVnode
    <span class="hljs-keyword">if</span> (isDef(i) &amp;&amp; isDef(i = i.data) &amp;&amp; isDef(i = i.registerRouteInstance)) {
      i(vm, callVal)
    }
  }
  <span class="hljs-comment">// &#x5168;&#x5C40;&#x6DF7;&#x5165;&#x94A9;&#x5B50;&#x51FD;&#x6570; &#x6BCF;&#x4E2A;&#x7EC4;&#x4EF6;&#x90FD;&#x4F1A;&#x6709;&#x8FD9;&#x4E9B;&#x94A9;&#x5B50;&#x51FD;&#x6570;&#xFF0C;&#x6267;&#x884C;&#x5C31;&#x4F1A;&#x8D70;&#x8FD9;&#x91CC;&#x7684;&#x903B;&#x8F91;</span>
  Vue.mixin({
    beforeCreate () {
      <span class="hljs-keyword">if</span> (isDef(<span class="hljs-keyword">this</span>.$options.router)) {
        <span class="hljs-comment">// new Vue &#x65F6;&#x4F20;&#x5165;&#x7684;&#x6839;&#x7EC4;&#x4EF6; router router&#x5BF9;&#x8C61;&#x4F20;&#x5165;&#x65F6;&#x5C31;&#x53EF;&#x4EE5;&#x62FF;&#x5230; this.$options.router</span>
        <span class="hljs-comment">// &#x6839; router</span>
        <span class="hljs-keyword">this</span>._routerRoot = <span class="hljs-keyword">this</span>
        <span class="hljs-keyword">this</span>._router = <span class="hljs-keyword">this</span>.$options.router
        <span class="hljs-keyword">this</span>._router.init(<span class="hljs-keyword">this</span>)
        <span class="hljs-comment">// &#x53D8;&#x6210;&#x54CD;&#x5E94;&#x5F0F;</span>
        Vue.util.defineReactive(<span class="hljs-keyword">this</span>, <span class="hljs-string">&apos;_route&apos;</span>, <span class="hljs-keyword">this</span>._router.history.current)
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// &#x975E;&#x6839;&#x7EC4;&#x4EF6;&#x8BBF;&#x95EE;&#x6839;&#x7EC4;&#x4EF6;&#x901A;&#x8FC7;$parent</span>
        <span class="hljs-keyword">this</span>._routerRoot = (<span class="hljs-keyword">this</span>.$parent &amp;&amp; <span class="hljs-keyword">this</span>.$parent._routerRoot) || <span class="hljs-keyword">this</span>
      }
      registerInstance(<span class="hljs-keyword">this</span>, <span class="hljs-keyword">this</span>)
    },
    destroyed () {
      registerInstance(<span class="hljs-keyword">this</span>)
    }
  })
  <span class="hljs-comment">// &#x539F;&#x578B;&#x52A0;&#x5165; $router &#x548C; $route</span>
  <span class="hljs-built_in">Object</span>.defineProperty(Vue.prototype, <span class="hljs-string">&apos;$router&apos;</span>, {
    get () { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._routerRoot._router }
  })
  <span class="hljs-built_in">Object</span>.defineProperty(Vue.prototype, <span class="hljs-string">&apos;$route&apos;</span>, {
    get () { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._routerRoot._route }
  })
<span class="hljs-comment">// &#x5168;&#x5C40;&#x6CE8;&#x518C;</span>
  Vue.component(<span class="hljs-string">&apos;RouterView&apos;</span>, View)
  Vue.component(<span class="hljs-string">&apos;RouterLink&apos;</span>, Link)
<span class="hljs-comment">// &#x83B7;&#x53D6;&#x5408;&#x5E76;&#x7B56;&#x7565;</span>
  <span class="hljs-keyword">const</span> strats = Vue.config.optionMergeStrategies
  <span class="hljs-comment">// use the same hook merging strategy for route hooks</span>
  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x6838;&#x5FC3;&#x90E8;&#x5206;&#x5C31;&#x662F;&#x5728;&#x6267;&#x884C; <code>install</code> &#x65B9;&#x6CD5;&#x65F6;&#x4F7F;&#x7528; <code>mixin</code> &#x7684;&#x65B9;&#x5F0F;&#x5C06;&#x6BCF;&#x4E2A;&#x7EC4;&#x4EF6;&#x90FD;&#x6DF7;&#x5165; <code>beforeCreate</code>,<code>destroyed</code> &#x8FD9;&#x4E24;&#x4E2A;&#x751F;&#x547D;&#x5468;&#x671F;&#x94A9;&#x5B50;&#x3002;&#x5728; <code>beforeCreate</code> &#x51FD;&#x6570;&#x4E2D;&#x4F1A;&#x53BB;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x4F20;&#x5165;&#x7684; <code>router</code> &#x5B9E;&#x4F8B;&#x662F;&#x5426;&#x662F;&#x6839;&#x7EC4;&#x4EF6;&#xFF0C;&#x5982;&#x679C;&#x662F;&#xFF0C;&#x5219;&#x5C06; <code>_routerRoot</code> &#x8D4B;&#x503C;&#x4E3A;&#x5F53;&#x524D;&#x7EC4;&#x4EF6;&#x5B9E;&#x4F8B;&#x3001;<code>_router</code> &#x8D4B;&#x503C;&#x4E3A;&#x4F20;&#x5165;&#x7684;<code>VueRouter</code> &#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#xFF0C;&#x63A5;&#x7740;&#x6267;&#x884C; <code>init</code> &#x65B9;&#x6CD5;&#x521D;&#x59CB;&#x5316; <code>router</code>,&#x7136;&#x540E;&#x5C06; <code>this_route</code> &#x54CD;&#x5E94;&#x5F0F;&#x5316;&#x3002;&#x975E;&#x6839;&#x7EC4;&#x4EF6;&#x7684;&#x8BDD; <code>_routerRoot</code> &#x6307;&#x5411; <code>$parent</code> &#x7236;&#x5B9E;&#x4F8B;&#x3002; &#x7136;&#x540E;&#x6267;&#x884C; <code>registerInstance(this,this)</code> &#x65B9;&#x6CD5;&#xFF0C;&#x8BE5;&#x65B9;&#x6CD5;&#x540E;&#x4F1A;,&#x63A5;&#x7740;&#x539F;&#x578B;&#x52A0;&#x5165; <code>$router</code> &#x548C; <code>$route</code>&#xFF0C;&#x6700;&#x540E;&#x6CE8;&#x518C; <code>RouterView</code> &#x548C; <code>RouterLink</code>&#xFF0C;&#x8FD9;&#x5C31;&#x662F;&#x6574;&#x4E2A; <code>install</code> &#x7684;&#x8FC7;&#x7A0B;&#x3002;</p>
<h4 id="&#x5C0F;&#x7ED3;"><a name="&#x5C0F;&#x7ED3;" class="anchor-navigation-ex-anchor" href="#&#x5C0F;&#x7ED3;"><i class="fa fa-link" aria-hidden="true"></i></a>&#x5C0F;&#x7ED3;</h4>
<p><code>Vue.use(plugin)</code> &#x5B9E;&#x9645;&#x4E0A;&#x5728;&#x6267;&#x884C; plugin&#x4E0A;&#x7684; <code>install</code> &#x65B9;&#x6CD5;&#xFF0C;<code>insatll</code> &#x65B9;&#x6CD5;&#x6709;&#x4E2A;&#x91CD;&#x8981;&#x7684;&#x6B65;&#x9AA4;:</p>
<ul>
<li>&#x4F7F;&#x7528; <code>mixin</code> &#x5728;&#x7EC4;&#x4EF6;&#x4E2D;&#x6DF7;&#x5165; <code>beforeCreate</code> , <code>destory</code> &#x8FD9;&#x4FE9;&#x4E2A;&#x751F;&#x547D;&#x5468;&#x671F;&#x94A9;&#x5B50;</li>
<li>&#x5728; <code>beforeCreate</code> &#x8FD9;&#x4E2A;&#x94A9;&#x5B50;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#x3002;</li>
<li>&#x5168;&#x5C40;&#x6CE8;&#x518C; <code>router-view</code>&#xFF0C;<code>router-link</code>&#x7EC4;&#x4EF6;</li>
</ul>
<h3 id="vuerouter"><a name="vuerouter" class="anchor-navigation-ex-anchor" href="#vuerouter"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.3. VueRouter</h3>
<p>&#x63A5;&#x7740;&#x5C31;&#x662F;&#x8FD9;&#x4E2A;&#x6700;&#x91CD;&#x8981;&#x7684; <code>class</code> : <code>VueRouter</code>&#x3002;&#x8FD9;&#x4E00;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#x6BD4;&#x8F83;&#x591A;&#xFF0C;&#x6240;&#x4EE5;&#x4E0D;&#x4E00;&#x4E00;&#x5217;&#x4E3E;&#xFF0C;&#x6311;&#x91CD;&#x70B9;&#x5206;&#x6790;&#x3002; <a href="https://github.com/vuejs/vue-router/blob/v3.1.2/src/index.js" target="_blank">vueRouter&#x6E90;&#x7801;&#x5730;&#x5740;</a>&#x3002;</p>
<h4 id="&#x6784;&#x9020;&#x51FD;&#x6570;"><a name="&#x6784;&#x9020;&#x51FD;&#x6570;" class="anchor-navigation-ex-anchor" href="#&#x6784;&#x9020;&#x51FD;&#x6570;"><i class="fa fa-link" aria-hidden="true"></i></a>&#x6784;&#x9020;&#x51FD;&#x6570;</h4>
<pre><code class="lang-javascript">  <span class="hljs-keyword">constructor</span> (options: RouterOptions = {}) {
    <span class="hljs-keyword">this</span>.app  = <span class="hljs-literal">null</span>
    <span class="hljs-keyword">this</span>.apps = []
    <span class="hljs-comment">// &#x4F20;&#x5165;&#x7684;&#x914D;&#x7F6E;&#x9879;</span>
    <span class="hljs-keyword">this</span>.options = options
    <span class="hljs-keyword">this</span>.beforeHooks = []
    <span class="hljs-keyword">this</span>.resolveHooks = []
    <span class="hljs-keyword">this</span>.afterHooks = []
    <span class="hljs-keyword">this</span>.matcher = createMatcher(options.routes || [], <span class="hljs-keyword">this</span>)
    <span class="hljs-comment">// &#x4E00;&#x822C;&#x5206;&#x4E24;&#x79CD;&#x6A21;&#x5F0F; hash &#x548C; history &#x8DEF;&#x7531; &#x7B2C;&#x4E09;&#x79CD;&#x662F;&#x62BD;&#x8C61;&#x6A21;&#x5F0F;</span>
    <span class="hljs-keyword">let</span> mode = options.mode || <span class="hljs-string">&apos;hash&apos;</span>
    <span class="hljs-comment">// &#x5224;&#x65AD;&#x5F53;&#x524D;&#x4F20;&#x5165;&#x7684;&#x914D;&#x7F6E;&#x662F;&#x5426;&#x80FD;&#x4F7F;&#x7528; history &#x6A21;&#x5F0F;</span>
    <span class="hljs-keyword">this</span>.fallback = mode === <span class="hljs-string">&apos;history&apos;</span> &amp;&amp; !supportsPushState &amp;&amp; options.fallback !== <span class="hljs-literal">false</span>
    <span class="hljs-comment">// &#x964D;&#x7EA7;&#x5904;&#x7406;</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.fallback) {
      mode = <span class="hljs-string">&apos;hash&apos;</span>
    }
    <span class="hljs-keyword">if</span> (!inBrowser) {
      mode = <span class="hljs-string">&apos;abstract&apos;</span>
    }
    <span class="hljs-keyword">this</span>.mode = mode
    <span class="hljs-comment">// &#x6839;&#x636E;&#x6A21;&#x5F0F;&#x5B9E;&#x4F8B;&#x5316;&#x4E0D;&#x540C;&#x7684; history,history &#x5BF9;&#x8C61;&#x4F1A;&#x5BF9;&#x8DEF;&#x7531;&#x8FDB;&#x884C;&#x7BA1;&#x7406; &#x7EE7;&#x627F;&#x4E8E;history class</span>
    <span class="hljs-keyword">switch</span> (mode) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;history&apos;</span>:
        <span class="hljs-keyword">this</span>.history = <span class="hljs-keyword">new</span> HTML5History(<span class="hljs-keyword">this</span>, options.base)
        <span class="hljs-keyword">break</span>
      <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;hash&apos;</span>:
        <span class="hljs-keyword">this</span>.history = <span class="hljs-keyword">new</span> HashHistory(<span class="hljs-keyword">this</span>, options.base, <span class="hljs-keyword">this</span>.fallback)
        <span class="hljs-keyword">break</span>
      <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;abstract&apos;</span>:
        <span class="hljs-keyword">this</span>.history = <span class="hljs-keyword">new</span> AbstractHistory(<span class="hljs-keyword">this</span>, options.base)
        <span class="hljs-keyword">break</span>
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">if</span> (process.env.NODE_ENV !== <span class="hljs-string">&apos;production&apos;</span>) {
          assert(<span class="hljs-literal">false</span>, <span class="hljs-string">`invalid mode: <span class="hljs-subst">${mode}</span>`</span>)
        }
    }
  }
</code></pre>
<p>&#x9996;&#x5148;&#x5728;&#x521D;&#x59CB;&#x5316; <code>vueRouter</code> &#x6574;&#x4E2A;&#x5BF9;&#x8C61;&#x65F6;&#x5B9A;&#x4E49;&#x4E86;&#x8BB8;&#x591A;&#x53D8;&#x91CF;&#xFF0C;<code>app</code> &#x4EE3;&#x8868; <code>Vue</code> &#x5B9E;&#x4F8B;&#xFF0C;<code>options</code> &#x4EE3;&#x8868;&#x4F20;&#x5165;&#x7684;&#x914D;&#x7F6E;&#x53C2;&#x6570;&#xFF0C;&#x7136;&#x540E;&#x5C31;&#x662F;&#x8DEF;&#x7531;&#x62E6;&#x622A;&#x6709;&#x7528;&#x7684; <code>hooks</code> &#x548C;&#x91CD;&#x8981;&#x7684; <code>matcher</code> (&#x540E;&#x6587;&#x4F1A;&#x5199;&#x5230;)&#x3002;&#x6784;&#x9020;&#x51FD;&#x6570;&#x5176;&#x5B9E;&#x5728;&#x505A;&#x4E24;&#x4EF6;&#x4E8B;&#x60C5;: 1. &#x786E;&#x5B9A;&#x5F53;&#x524D;&#x8DEF;&#x7531;&#x4F7F;&#x7528;&#x7684; <code>mode</code>2. &#x5B9E;&#x4F8B;&#x5316;&#x5BF9;&#x5E94;&#x7684; <code>history</code> &#x5BF9;&#x8C61;&#x3002;</p>
<h4 id="init"><a name="init" class="anchor-navigation-ex-anchor" href="#init"><i class="fa fa-link" aria-hidden="true"></i></a>init</h4>
<p>&#x63A5;&#x7740;&#x5B8C;&#x6210;&#x5B9E;&#x4F8B;&#x5316; <code>vueRouter</code> &#x4E4B;&#x540E;&#xFF0C;&#x5982;&#x679C;&#x8FD9;&#x4E2A;&#x5B9E;&#x4F8B;&#x4F20;&#x5165;&#x540E;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x521A;&#x5F00;&#x59CB;&#x8BF4;&#x7684;&#x5C06; <code>vueRouter</code> &#x5B9E;&#x4F8B;&#x5728;&#x521D;&#x59CB;&#x5316; <code>Vue</code> &#x65F6;&#x4F20;&#x5165;&#xFF0C;&#x5B83;&#x4F1A;&#x5728;&#x6267;&#x884C; <code>beforeCreate</code> &#x65F6;&#x6267;&#x884C; <code>init</code> &#x65B9;&#x6CD5;</p>
<pre><code class="lang-javascript">init (app: any) {
  ...
  this.apps.push(app)
  <span class="hljs-comment">// &#x786E;&#x4FDD;&#x540E;&#x9762;&#x7684;&#x903B;&#x8F91;&#x53EA;&#x8D70;&#x4E00;&#x6B21;</span>
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.app) {
    <span class="hljs-keyword">return</span>
  }
  <span class="hljs-comment">// &#x4FDD;&#x5B58; Vue &#x5B9E;&#x4F8B;</span>
  <span class="hljs-keyword">this</span>.app = app
  <span class="hljs-keyword">const</span> history = <span class="hljs-keyword">this</span>.history
  <span class="hljs-comment">// &#x62FF;&#x5230; history &#x5B9E;&#x4F8B;&#x4E4B;&#x540E;&#xFF0C;&#x8C03;&#x7528; transitionTo &#x8FDB;&#x884C;&#x8DEF;&#x7531;&#x8FC7;&#x6E21;</span>
  <span class="hljs-keyword">if</span> (history <span class="hljs-keyword">instanceof</span> HTML5History) {
    history.transitionTo(history.getCurrentLocation())
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (history <span class="hljs-keyword">instanceof</span> HashHistory) {
    <span class="hljs-keyword">const</span> setupHashListener = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
      history.setupListeners()
    }
    history.transitionTo(
      history.getCurrentLocation(),
      setupHashListener,
      setupHashListener
    )
  }
}
</code></pre>
<p><code>init</code> &#x65B9;&#x6CD5;&#x4F20;&#x5165; <code>Vue</code> &#x5B9E;&#x4F8B;&#xFF0C;&#x4FDD;&#x5B58;&#x5230; <code>this.apps</code> &#x5F53;&#x4E2D;&#x3002;<code>Vue&#x5B9E;&#x4F8B;</code> &#x4F1A;&#x53D6;&#x51FA;&#x5F53;&#x524D;&#x7684; <code>this.history</code>&#xFF0C;&#x5982;&#x679C;&#x662F;&#x54C8;&#x5E0C;&#x8DEF;&#x7531;&#xFF0C;&#x5148;&#x8D70; <code>setupHashListener</code> &#x51FD;&#x6570;&#xFF0C;&#x7136;&#x540E;&#x8C03;&#x4E00;&#x4E2A;&#x5173;&#x952E;&#x7684;&#x51FD;&#x6570; <code>transitionTo</code> &#x8DEF;&#x7531;&#x8FC7;&#x6E21;,&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#x5176;&#x5B9E;&#x8C03;&#x7528;&#x4E86; <code>this.matcher.match</code> &#x53BB;&#x5339;&#x914D;&#x3002;</p>
<h4 id="&#x5C0F;&#x7ED3;_1"><a name="&#x5C0F;&#x7ED3;_1" class="anchor-navigation-ex-anchor" href="#&#x5C0F;&#x7ED3;_1"><i class="fa fa-link" aria-hidden="true"></i></a>&#x5C0F;&#x7ED3;</h4>
<p>&#x9996;&#x5148;&#x5728; <code>vueRouter</code> &#x6784;&#x9020;&#x51FD;&#x6570;&#x6267;&#x884C;&#x5B8C;&#x4F1A;&#x5B8C;&#x6210;&#x8DEF;&#x7531;&#x6A21;&#x5F0F;&#x7684;&#x9009;&#x62E9;&#xFF0C;&#x751F;&#x6210; <code>matcher</code> ,&#x7136;&#x540E;&#x521D;&#x59CB;&#x5316;&#x8DEF;&#x7531;&#x9700;&#x8981;&#x4F20;&#x5165; <code>vueRouter</code> &#x5B9E;&#x4F8B;&#x5BF9;&#x8C61;&#xFF0C;&#x5728;&#x7EC4;&#x4EF6;&#x521D;&#x59CB;&#x5316;&#x9636;&#x6BB5;&#x6267;&#x884C; <code>beforeCreate</code> &#x94A9;&#x5B50;&#xFF0C;&#x8C03;&#x7528; <code>init</code> &#x65B9;&#x6CD5;&#xFF0C;&#x63A5;&#x7740;&#x62FF;&#x5230; <code>this.history</code> &#x53BB;&#x8C03;&#x7528; <code>transitionTo</code> &#x8FDB;&#x884C;&#x8DEF;&#x7531;&#x8FC7;&#x6E21;&#x3002;</p>
<h3 id="matcher"><a name="matcher" class="anchor-navigation-ex-anchor" href="#matcher"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.4. Matcher</h3>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_145809415_0.png" alt="66"></p>
<p>&#x4E4B;&#x524D;&#x5728; <code>vueRouter</code> &#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#x4E2D;&#x521D;&#x59CB;&#x5316;&#x4E86; <code>macther</code>,&#x672C;&#x8282;&#x5C06;&#x8BE6;&#x7EC6;&#x5206;&#x6790;&#x4E0B;&#x9762;&#x8FD9;&#x53E5;&#x4EE3;&#x7801;&#x5230;&#x5E95;&#x5728;&#x505A;&#x4EC0;&#x4E48;&#x4E8B;&#x60C5;,&#x4EE5;&#x53CA; <code>match</code> &#x65B9;&#x6CD5;&#x5728;&#x505A;&#x4EC0;&#x4E48;<a href="https://github.com/vuejs/vue-router/blob/dev/src/create-matcher.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a>&#x3002;</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">this</span>.matcher = createMatcher(options.routes || [], <span class="hljs-keyword">this</span>)
</code></pre>
<p>&#x9996;&#x5148;&#x5C06;&#x4EE3;&#x7801;&#x5B9A;&#x4F4D;&#x5230;<code>create-matcher.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createMatcher</span> (<span class="hljs-params">
  routes: Array&lt;RouteConfig&gt;,
  router: VueRouter
</span>): <span class="hljs-title">Matcher</span> </span>{
  <span class="hljs-comment">// &#x521B;&#x5EFA;&#x6620;&#x5C04;&#x8868;</span>
  <span class="hljs-keyword">const</span> { pathList, pathMap, nameMap } = createRouteMap(routes)
  <span class="hljs-comment">// &#x6DFB;&#x52A0;&#x52A8;&#x6001;&#x8DEF;&#x7531;</span>
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addRoutes</span>(<span class="hljs-params">routes</span>)</span>{...}
  <span class="hljs-comment">// &#x8BA1;&#x7B97;&#x65B0;&#x8DEF;&#x5F84;</span>
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">match</span> (<span class="hljs-params">
    raw: RawLocation,
    currentRoute?: Route,
    redirectedFrom?: Location
  </span>): <span class="hljs-title">Route</span> </span>{...}
  <span class="hljs-comment">// ... &#x540E;&#x9762;&#x7684;&#x4E00;&#x4E9B;&#x65B9;&#x6CD5;&#x6682;&#x4E0D;&#x5C55;&#x5F00;</span>

   <span class="hljs-keyword">return</span> {
    match,
    addRoutes
  }
}
</code></pre>
<p><code>createMatcher</code> &#x63A5;&#x53D7;&#x4FE9;&#x53C2;&#x6570;,&#x5206;&#x522B;&#x662F; <code>routes</code>,&#x8FD9;&#x4E2A;&#x5C31;&#x662F;&#x6211;&#x4EEC;&#x5E73;&#x65F6;&#x5728; <code>router.js</code> &#x5B9A;&#x4E49;&#x7684;&#x8DEF;&#x7531;&#x8868;&#x914D;&#x7F6E;&#xFF0C;&#x7136;&#x540E;&#x8FD8;&#x6709;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F; <code>router</code> &#x4ED6;&#x662F; <code>new vueRouter</code> &#x8FD4;&#x56DE;&#x7684;&#x5B9E;&#x4F8B;&#x3002;</p>
<h4 id="createroutemap"><a name="createroutemap" class="anchor-navigation-ex-anchor" href="#createroutemap"><i class="fa fa-link" aria-hidden="true"></i></a>createRouteMap</h4>
<p>&#x4E0B;&#x9762;&#x8FD9;&#x53E5;&#x4EE3;&#x7801;&#x662F;&#x5728;&#x521B;&#x5EFA;&#x4E00;&#x5F20; <code>path-record</code>,<code>name-record</code> &#x7684;&#x6620;&#x5C04;&#x8868;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x4EE3;&#x7801;&#x5B9A;&#x4F4D;&#x5230; <code>create-route-map.js</code> <a href="https://github.com/vuejs/vue-router/blob/dev/src/create-route-map.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createRouteMap</span> (<span class="hljs-params">
  routes: Array&lt;RouteConfig&gt;,
  oldPathList?: Array&lt;string&gt;,
  oldPathMap?: Dictionary&lt;RouteRecord&gt;,
  oldNameMap?: Dictionary&lt;RouteRecord&gt;
</span>): </span>{
  pathList: <span class="hljs-built_in">Array</span>&lt;string&gt;,
  <span class="hljs-attr">pathMap</span>: Dictionary&lt;RouteRecord&gt;,
  <span class="hljs-attr">nameMap</span>: Dictionary&lt;RouteRecord&gt;
} {
  <span class="hljs-comment">// &#x8BB0;&#x5F55;&#x6240;&#x6709;&#x7684; path</span>
  <span class="hljs-keyword">const</span> pathList: <span class="hljs-built_in">Array</span>&lt;string&gt; = oldPathList || []
  <span class="hljs-comment">// &#x8BB0;&#x5F55; path-RouteRecord &#x7684; Map</span>
  <span class="hljs-keyword">const</span> pathMap: Dictionary&lt;RouteRecord&gt; = oldPathMap || <span class="hljs-built_in">Object</span>.create(<span class="hljs-literal">null</span>)
   <span class="hljs-comment">// &#x8BB0;&#x5F55; name-RouteRecord &#x7684; Map</span>
  <span class="hljs-keyword">const</span> nameMap: Dictionary&lt;RouteRecord&gt; = oldNameMap || <span class="hljs-built_in">Object</span>.create(<span class="hljs-literal">null</span>)
  <span class="hljs-comment">// &#x904D;&#x5386;&#x6240;&#x6709;&#x7684; route &#x751F;&#x6210;&#x5BF9;&#x5E94;&#x6620;&#x5C04;&#x8868;</span>
  routes.forEach(<span class="hljs-function"><span class="hljs-params">route</span> =&gt;</span> {
    addRouteRecord(pathList, pathMap, nameMap, route)
  })
  <span class="hljs-comment">// &#x8C03;&#x6574;&#x4F18;&#x5148;&#x7EA7;</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>, l = pathList.length; i &lt; l; i++) {
    <span class="hljs-keyword">if</span> (pathList[i] === <span class="hljs-string">&apos;*&apos;</span>) {
      pathList.push(pathList.splice(i, <span class="hljs-number">1</span>)[<span class="hljs-number">0</span>])
      l--
      i--
    }
  }
  <span class="hljs-keyword">return</span> {
    pathList,
    pathMap,
    nameMap
  }
}
</code></pre>
<p><code>createRouteMap</code> &#x9700;&#x8981;&#x4F20;&#x5165;&#x8DEF;&#x7531;&#x914D;&#x7F6E;&#xFF0C;&#x652F;&#x6301;&#x4F20;&#x5165;&#x65E7;&#x8DEF;&#x5F84;&#x6570;&#x7EC4;&#x548C;&#x65E7;&#x7684; <code>Map</code> &#x8FD9;&#x4E00;&#x6B65;&#x662F;&#x4E3A;&#x540E;&#x9762;&#x9012;&#x5F52;&#x548C; <code>addRoutes</code> &#x505A;&#x597D;&#x51C6;&#x5907;&#x3002; &#x9996;&#x5148;&#x7528;&#x4E09;&#x4E2A;&#x53D8;&#x91CF;&#x8BB0;&#x5F55; <code>path</code>,<code>pathMap</code>,<code>nameMap</code>&#xFF0C;&#x63A5;&#x7740;&#x6211;&#x4EEC;&#x6765;&#x770B; <code>addRouteRecord</code> &#x8FD9;&#x4E2A;&#x6838;&#x5FC3;&#x65B9;&#x6CD5;&#x3002; &#x8FD9;&#x4E00;&#x5757;&#x4EE3;&#x7801;&#x592A;&#x591A;&#x4E86;&#xFF0C;&#x5217;&#x4E3E;&#x51E0;&#x4E2A;&#x91CD;&#x8981;&#x7684;&#x6B65;&#x9AA4;</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// &#x89E3;&#x6790;&#x8DEF;&#x5F84;</span>
<span class="hljs-keyword">const</span> pathToRegexpOptions: PathToRegexpOptions =
    route.pathToRegexpOptions || {}
<span class="hljs-comment">// &#x62FC;&#x63A5;&#x8DEF;&#x5F84;</span>
<span class="hljs-keyword">const</span> normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict)
<span class="hljs-comment">// &#x8BB0;&#x5F55;&#x8DEF;&#x7531;&#x4FE1;&#x606F;&#x7684;&#x5173;&#x952E;&#x5BF9;&#x8C61;&#xFF0C;&#x540E;&#x7EED;&#x4F1A;&#x4F9D;&#x6B64;&#x5EFA;&#x7ACB;&#x6620;&#x5C04;&#x8868;</span>
<span class="hljs-keyword">const</span> record: RouteRecord = {
  <span class="hljs-attr">path</span>: normalizedPath,
  <span class="hljs-attr">regex</span>: compileRouteRegex(normalizedPath, pathToRegexpOptions),
  <span class="hljs-comment">// route &#x5BF9;&#x5E94;&#x7684;&#x7EC4;&#x4EF6;</span>
  components: route.components || { <span class="hljs-attr">default</span>: route.component },
  <span class="hljs-comment">// &#x7EC4;&#x4EF6;&#x5B9E;&#x4F8B;</span>
  instances: {},
  name,
  parent,
  matchAs,
  <span class="hljs-attr">redirect</span>: route.redirect,
  <span class="hljs-attr">beforeEnter</span>: route.beforeEnter,
  <span class="hljs-attr">meta</span>: route.meta || {},
  <span class="hljs-attr">props</span>: route.props == <span class="hljs-literal">null</span>
    ? {}
    : route.components
      ? route.props
      : { <span class="hljs-attr">default</span>: route.props }
}
</code></pre>
<p>&#x4F7F;&#x7528; <code>recod</code> &#x5BF9;&#x8C61; &#x8BB0;&#x5F55;&#x8DEF;&#x7531;&#x914D;&#x7F6E;&#x6709;&#x5229;&#x4E8E;&#x540E;&#x7EED;&#x8DEF;&#x5F84;&#x5207;&#x6362;&#x65F6;&#x8BA1;&#x7B97;&#x51FA;&#x65B0;&#x8DEF;&#x5F84;&#xFF0C;&#x8FD9;&#x91CC;&#x7684; <code>path</code> &#x5176;&#x5B9E;&#x662F;&#x901A;&#x8FC7;&#x4F20;&#x5165;&#x7236;&#x7EA7; <code>record</code> &#x5BF9;&#x8C61;&#x7684;<code>path</code>&#x548C;&#x5F53;&#x524D; <code>path</code> &#x62FC;&#x63A5;&#x51FA;&#x6765;&#x7684;  &#x3002;&#x7136;&#x540E; <code>regex</code> &#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x5E93;&#x5C06; <code>path</code> &#x89E3;&#x6790;&#x4E3A;&#x6B63;&#x5219;&#x8868;&#x8FBE;&#x5F0F;&#x3002; &#x5982;&#x679C; <code>route</code> &#x6709;&#x5B50;&#x8282;&#x70B9;&#x5C31;&#x9012;&#x5F52;&#x8C03;&#x7528; <code>addRouteRecord</code></p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// &#x5982;&#x679C;&#x6709; children &#x9012;&#x5F52;&#x8C03;&#x7528; addRouteRecord</span>
route.children.forEach(<span class="hljs-function"><span class="hljs-params">child</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> childMatchAs = matchAs
    ? cleanPath(<span class="hljs-string">`<span class="hljs-subst">${matchAs}</span>/<span class="hljs-subst">${child.path}</span>`</span>)
    : <span class="hljs-literal">undefined</span>
    addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs)
})
</code></pre>
<p>&#x6700;&#x540E;&#x6620;&#x5C04;&#x4E24;&#x5F20;&#x8868;,&#x5E76;&#x5C06; <code>record&#xB7;path</code> &#x4FDD;&#x5B58;&#x8FDB; <code>pathList</code>,<code>nameMap</code> &#x903B;&#x8F91;&#x76F8;&#x4F3C;&#x5C31;&#x4E0D;&#x5217;&#x4E3E;&#x4E86;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (!pathMap[record.path]) {
    pathList.push(record.path)
    pathMap[record.path] = record
}
</code></pre>
<p>&#x5E9F;&#x4E86;&#x8FD9;&#x4E48;&#x5927;&#x52B2;&#x5C06; <code>pathList</code> &#x548C; <code>pathMap</code> &#x548C; <code>nameMap</code> &#x62BD;&#x51FA;&#x6765;&#x662F;&#x4E3A;&#x5565;&#x5462;? &#x9996;&#x5148; <code>pathList</code> &#x662F;&#x8BB0;&#x5F55;&#x8DEF;&#x7531;&#x914D;&#x7F6E;&#x6240;&#x6709;&#x7684; <code>path</code>&#xFF0C;&#x7136;&#x540E; <code>pathMap</code> &#x548C; <code>nameMap</code> &#x65B9;&#x4FBF;&#x6211;&#x4EEC;&#x4F20;&#x5165; <code>path</code> &#x6216;&#x8005; <code>name</code> &#x5FEB;&#x901F;&#x5B9A;&#x4F4D;&#x5230;&#x4E00;&#x4E2A; <code>record</code>,&#x7136;&#x540E;&#x8F85;&#x52A9;&#x540E;&#x7EED;&#x8DEF;&#x5F84;&#x5207;&#x6362;&#x8BA1;&#x7B97;&#x8DEF;&#x7531;&#x7684;&#x3002;</p>
<h4 id="addroutes"><a name="addroutes" class="anchor-navigation-ex-anchor" href="#addroutes"><i class="fa fa-link" aria-hidden="true"></i></a>addRoutes</h4>
<p>&#x8FD9;&#x662F;&#x5728; <code>vue2.2.0</code> &#x4E4B;&#x540E;&#x65B0;&#x6DFB;&#x52A0;&#x7684; <code>api</code> ,&#x6216;&#x8BB8;&#x5F88;&#x591A;&#x60C5;&#x51B5;&#x8DEF;&#x7531;&#x5E76;&#x4E0D;&#x662F;&#x5199;&#x6B7B;&#x7684;&#xFF0C;&#x9700;&#x8981;&#x52A8;&#x6001;&#x6DFB;&#x52A0;&#x8DEF;&#x7531;&#x3002;&#x6709;&#x4E86;&#x524D;&#x9762;&#x7684; <code>createRouteMap</code> &#x7684;&#x57FA;&#x7840;&#x4E0A;&#x6211;&#x4EEC;&#x53EA;&#x9700;&#x8981;&#x4F20;&#x5165; <code>routes</code> &#x5373;&#x53EF;&#xFF0C;&#x4ED6;&#x5C31;&#x80FD;&#x5728;&#x539F;&#x57FA;&#x7840;&#x4E0A;&#x4FEE;&#x6539;</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addRoutes</span> (<span class="hljs-params">routes</span>) </span>{
  createRouteMap(routes, pathList, pathMap, nameMap)
}
</code></pre>
<p>&#x5E76;&#x4E14;&#x770B;&#x5230;&#x5728; <code>createMathcer</code> &#x6700;&#x540E;&#x8FD4;&#x56DE;&#x4E86;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x5C31;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">return</span> {
    match,
    addRoutes
  }
</code></pre>
<h4 id="match"><a name="match" class="anchor-navigation-ex-anchor" href="#match"><i class="fa fa-link" aria-hidden="true"></i></a>match</h4>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">match</span> (<span class="hljs-params">
  raw: RawLocation,
  currentRoute?: Route,
  redirectedFrom?: Location
</span>): <span class="hljs-title">Route</span> </span>{
  ...
}
</code></pre>
<p>&#x63A5;&#x4E0B;&#x6765;&#x5C31;&#x662F; <code>match</code> &#x65B9;&#x6CD5;&#xFF0C;&#x5B83;&#x63A5;&#x6536; 3 &#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x5176;&#x4E2D; <code>raw</code> &#x662F; <code>RawLocation</code> &#x7C7B;&#x578B;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A; <code>url</code> &#x5B57;&#x7B26;&#x4E32;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A; <code>Location</code> &#x5BF9;&#x8C61;&#xFF1B;<code>currentRoute</code> &#x662F; <code>Route</code> &#x7C7B;&#x578B;&#xFF0C;&#x5B83;&#x8868;&#x793A;&#x5F53;&#x524D;&#x7684;&#x8DEF;&#x5F84;&#xFF1B;<code>redirectedFrom</code> &#x548C;&#x91CD;&#x5B9A;&#x5411;&#x76F8;&#x5173;&#x3002; <code>match</code> &#x65B9;&#x6CD5;&#x8FD4;&#x56DE;&#x7684;&#x662F;&#x4E00;&#x4E2A;&#x8DEF;&#x5F84;&#xFF0C;&#x5B83;&#x7684;&#x4F5C;&#x7528;&#x662F;&#x6839;&#x636E;&#x4F20;&#x5165;&#x7684; <code>raw</code> &#x548C;&#x5F53;&#x524D;&#x7684;&#x8DEF;&#x5F84; <code>currentRoute</code> &#x8BA1;&#x7B97;&#x51FA;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x8DEF;&#x5F84;&#x5E76;&#x8FD4;&#x56DE;&#x3002;&#x81F3;&#x4E8E;&#x4ED6;&#x662F;&#x5982;&#x4F55;&#x8BA1;&#x7B97;&#x51FA;&#x8FD9;&#x6761;&#x8DEF;&#x5F84;&#x7684;,&#x53EF;&#x4EE5;&#x8BE6;&#x7EC6;&#x770B;&#x4E00;&#x4E0B;&#x5982;&#x4F55;&#x8BA1;&#x7B97;&#x51FA;<code>location</code>&#x7684; <code>normalizeLocation</code> &#x65B9;&#x6CD5;&#x548C; <code>_createRoute</code> &#x65B9;&#x6CD5;&#x3002;</p>
<h4 id="&#x5C0F;&#x7ED3;_2"><a name="&#x5C0F;&#x7ED3;_2" class="anchor-navigation-ex-anchor" href="#&#x5C0F;&#x7ED3;_2"><i class="fa fa-link" aria-hidden="true"></i></a>&#x5C0F;&#x7ED3;</h4>
<ul>
<li><code>createMatcher</code>: &#x6839;&#x636E;&#x8DEF;&#x7531;&#x7684;&#x914D;&#x7F6E;&#x63CF;&#x8FF0;&#x5EFA;&#x7ACB;&#x6620;&#x5C04;&#x8868;&#xFF0C;&#x5305;&#x62EC;&#x8DEF;&#x5F84;&#x3001;&#x540D;&#x79F0;&#x5230;&#x8DEF;&#x7531; <code>record</code> &#x7684;&#x6620;&#x5C04;&#x5173;&#x7CFB;, &#x6700;&#x91CD;&#x8981;&#x7684;&#x5C31;&#x662F; <code>createRouteMap</code> &#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x8FD9;&#x91CC;&#x4E5F;&#x662F;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5339;&#x914D;&#x548C;&#x5D4C;&#x5957;&#x8DEF;&#x7531;&#x7684;&#x539F;&#x7406;&#x3002;</li>
<li><code>addRoutes</code>: &#x52A8;&#x6001;&#x6DFB;&#x52A0;&#x8DEF;&#x7531;&#x914D;&#x7F6E;</li>
<li><code>match</code>: &#x6839;&#x636E;&#x4F20;&#x5165;&#x7684; <code>raw</code> &#x548C;&#x5F53;&#x524D;&#x7684;&#x8DEF;&#x5F84; <code>currentRoute</code> &#x8BA1;&#x7B97;&#x51FA;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x8DEF;&#x5F84;&#x5E76;&#x8FD4;&#x56DE;&#x3002;</li>
</ul>
<h3 id="&#x8DEF;&#x7531;&#x6A21;&#x5F0F;"><a name="&#x8DEF;&#x7531;&#x6A21;&#x5F0F;" class="anchor-navigation-ex-anchor" href="#&#x8DEF;&#x7531;&#x6A21;&#x5F0F;"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.5. &#x8DEF;&#x7531;&#x6A21;&#x5F0F;</h3>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_160134247_0.png" alt="68"></p>
<p><code>vue-router</code> &#x652F;&#x6301;&#x4E09;&#x79CD;&#x8DEF;&#x7531;&#x6A21;&#x5F0F;(mode)&#xFF1A;<code>hash</code>&#x3001;<code>history</code>&#x3001;<code>abstract</code>&#xFF0C;&#x5176;&#x4E2D; <code>abstract</code> &#x662F;&#x5728;&#x975E;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x4E0B;&#x4F7F;&#x7528;&#x7684;&#x8DEF;&#x7531;&#x6A21;&#x5F0F;<a href="https://github.com/vuejs/vue-router/blob/dev/src/index.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a>&#x3002;</p>
<p>&#x8FD9;&#x4E00;&#x90E8;&#x5206;&#x5728;&#x524D;&#x9762;&#x521D;&#x59CB;&#x5316; <code>vueRouter</code> &#x5BF9;&#x8C61;&#x65F6;&#x63D0;&#x5230;&#x8FC7;,&#x9996;&#x5148;&#x62FF;&#x5230;&#x914D;&#x7F6E;&#x9879;&#x7684;&#x6A21;&#x5F0F;&#xFF0C;&#x7136;&#x540E;&#x6839;&#x636E;&#x5F53;&#x524D;&#x4F20;&#x5165;&#x7684;&#x914D;&#x7F6E;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x6D4F;&#x89C8;&#x5668;&#x662F;&#x5426;&#x652F;&#x6301;&#x8FD9;&#x79CD;&#x6A21;&#x5F0F;&#xFF0C;&#x9ED8;&#x8BA4; <code>ie9</code> &#x4EE5;&#x4E0B;&#x4F1A;&#x964D;&#x7EA7;&#x4E3A; <code>hash</code>&#x3002; &#x7136;&#x540E;&#x6839;&#x636E;&#x4E0D;&#x540C;&#x7684;&#x6A21;&#x5F0F;&#x53BB;&#x521D;&#x59CB;&#x5316;&#x4E0D;&#x540C;&#x7684; <code>history</code> &#x5B9E;&#x4F8B;&#x3002;</p>
<pre><code class="lang-javascript">    <span class="hljs-comment">// &#x4E00;&#x822C;&#x5206;&#x4E24;&#x79CD;&#x6A21;&#x5F0F; hash &#x548C; history &#x8DEF;&#x7531; &#x7B2C;&#x4E09;&#x79CD;&#x662F;&#x62BD;&#x8C61;&#x6A21;&#x5F0F;&#x4E0D;&#x5E38;&#x7528;</span>
    <span class="hljs-keyword">let</span> mode = options.mode || <span class="hljs-string">&apos;hash&apos;</span>
    <span class="hljs-comment">// &#x5224;&#x65AD;&#x5F53;&#x524D;&#x4F20;&#x5165;&#x7684;&#x914D;&#x7F6E;&#x662F;&#x5426;&#x80FD;&#x4F7F;&#x7528; history &#x6A21;&#x5F0F;</span>
    <span class="hljs-keyword">this</span>.fallback = mode === <span class="hljs-string">&apos;history&apos;</span> &amp;&amp; !supportsPushState &amp;&amp; options.fallback !== <span class="hljs-literal">false</span>
    <span class="hljs-comment">// &#x964D;&#x7EA7;&#x5904;&#x7406;</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.fallback) {
      mode = <span class="hljs-string">&apos;hash&apos;</span>
    }
    <span class="hljs-keyword">if</span> (!inBrowser) {
      mode = <span class="hljs-string">&apos;abstract&apos;</span>
    }
    <span class="hljs-keyword">this</span>.mode = mode
    <span class="hljs-comment">// &#x6839;&#x636E;&#x6A21;&#x5F0F;&#x5B9E;&#x4F8B;&#x5316;&#x4E0D;&#x540C;&#x7684; history history &#x5BF9;&#x8C61;&#x4F1A;&#x5BF9;&#x8DEF;&#x7531;&#x8FDB;&#x884C;&#x7BA1;&#x7406; &#x7EE7;&#x627F;&#x4E8E; history class</span>
    <span class="hljs-keyword">switch</span> (mode) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;history&apos;</span>:
        <span class="hljs-keyword">this</span>.history = <span class="hljs-keyword">new</span> HTML5History(<span class="hljs-keyword">this</span>, options.base)
        <span class="hljs-keyword">break</span>
      <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;hash&apos;</span>:
        <span class="hljs-keyword">this</span>.history = <span class="hljs-keyword">new</span> HashHistory(<span class="hljs-keyword">this</span>, options.base, <span class="hljs-keyword">this</span>.fallback)
        <span class="hljs-keyword">break</span>
      <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;abstract&apos;</span>:
        <span class="hljs-keyword">this</span>.history = <span class="hljs-keyword">new</span> AbstractHistory(<span class="hljs-keyword">this</span>, options.base)
        <span class="hljs-keyword">break</span>
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">if</span> (process.env.NODE_ENV !== <span class="hljs-string">&apos;production&apos;</span>) {
          assert(<span class="hljs-literal">false</span>, <span class="hljs-string">`invalid mode: <span class="hljs-subst">${mode}</span>`</span>)
        }
    }
</code></pre>
<h4 id="&#x5C0F;&#x7ED3;_3"><a name="&#x5C0F;&#x7ED3;_3" class="anchor-navigation-ex-anchor" href="#&#x5C0F;&#x7ED3;_3"><i class="fa fa-link" aria-hidden="true"></i></a>&#x5C0F;&#x7ED3;</h4>
<p><code>vue-router</code> &#x652F;&#x6301;&#x4E09;&#x79CD;&#x8DEF;&#x7531;&#x6A21;&#x5F0F;&#xFF0C;<code>hash</code>&#x3001;<code>history</code>&#x548C;<code>abstract</code>&#x3002;&#x9ED8;&#x8BA4;&#x4E3A; <code>hash</code> ,&#x5982;&#x679C;&#x5F53;&#x524D;&#x6D4F;&#x89C8;&#x5668;&#x4E0D;&#x652F;&#x6301;<code>history</code>&#x5219;&#x4F1A;&#x505A;&#x964D;&#x7EA7;&#x5904;&#x7406;&#xFF0C;&#x7136;&#x540E;&#x5B8C;&#x6210; <code>history</code> &#x7684;&#x521D;&#x59CB;&#x5316;&#x3002;</p>
<h3 id="&#x8DEF;&#x7531;&#x5207;&#x6362;"><a name="&#x8DEF;&#x7531;&#x5207;&#x6362;" class="anchor-navigation-ex-anchor" href="#&#x8DEF;&#x7531;&#x5207;&#x6362;"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.6. &#x8DEF;&#x7531;&#x5207;&#x6362;</h3>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_160445083_0.png" alt="69"></p>
<p>&#x5207;&#x6362; url &#x4E3B;&#x8981;&#x662F;&#x8C03;&#x7528;&#x4E86; <code>push</code> &#x65B9;&#x6CD5;&#xFF0C;&#x4E0B;&#x9762;&#x4EE5;&#x54C8;&#x5E0C;&#x6A21;&#x5F0F;&#x4E3A;&#x4F8B;&#xFF0C;&#x5206;&#x6790;<code>push</code>&#x65B9;&#x6CD5;&#x5B9E;&#x73B0;&#x7684;&#x539F;&#x7406; &#x3002;<code>push</code> &#x65B9;&#x6CD5;&#x5207;&#x6362;&#x8DEF;&#x7531;&#x7684;&#x5B9E;&#x73B0;&#x539F;&#x7406; <a href="https://github.com/vuejs/vue-router/blob/dev/src/history/hash.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<p>&#x9996;&#x5148;&#x5728; <code>src/index.js</code> &#x4E0B;&#x627E;&#x5230; <code>vueRouter</code> &#x5B9A;&#x4E49;&#x7684; <code>push</code> &#x65B9;&#x6CD5;</p>
<pre><code class="lang-javascript">  push (location: RawLocation, onComplete?: <span class="hljs-built_in">Function</span>, onAbort?: <span class="hljs-built_in">Function</span>) {
    <span class="hljs-comment">// $flow-disable-line</span>
    <span class="hljs-keyword">if</span> (!onComplete &amp;&amp; !onAbort &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">Promise</span> !== <span class="hljs-string">&apos;undefined&apos;</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
        <span class="hljs-keyword">this</span>.history.push(location, resolve, reject)
      })
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">this</span>.history.push(location, onComplete, onAbort)
    }
  }
</code></pre>
<p>&#x63A5;&#x7740;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x5B9A;&#x4F4D;&#x5230; <code>history/hash.js</code>&#x3002;&#x8FD9;&#x91CC;&#x9996;&#x5148;&#x83B7;&#x53D6;&#x5230;&#x5F53;&#x524D;&#x8DEF;&#x5F84;&#x7136;&#x540E;&#x8C03;&#x7528;&#x4E86; <code>transitionTo</code> &#x505A;&#x8DEF;&#x5F84;&#x5207;&#x6362;&#xFF0C;&#x5728;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x5F53;&#x4E2D;&#x6267;&#x884C; <code>pushHash</code> &#x8FD9;&#x4E2A;&#x6838;&#x5FC3;&#x65B9;&#x6CD5;&#x3002;</p>
<pre><code class="lang-javascript">push (location: RawLocation, onComplete?: <span class="hljs-built_in">Function</span>, onAbort?: <span class="hljs-built_in">Function</span>) {
    <span class="hljs-keyword">const</span> { <span class="hljs-attr">current</span>: fromRoute } = <span class="hljs-keyword">this</span>
    <span class="hljs-comment">// &#x8DEF;&#x5F84;&#x5207;&#x6362;&#x7684;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x4E2D;&#x8C03;&#x7528; pushHash</span>
    <span class="hljs-keyword">this</span>.transitionTo(
      location,
      route =&gt; {
        pushHash(route.fullPath)
        handleScroll(<span class="hljs-keyword">this</span>.router, route, fromRoute, <span class="hljs-literal">false</span>)
        onComplete &amp;&amp; onComplete(route)
      },
      onAbort
    )
  }
</code></pre>
<p>&#x800C; <code>pushHash</code> &#x65B9;&#x6CD5;&#x5728;&#x505A;&#x5B8C;&#x6D4F;&#x89C8;&#x5668;&#x517C;&#x5BB9;&#x5224;&#x65AD;&#x540E;&#x8C03;&#x7528;&#x7684; <code>pushState</code> &#x65B9;&#x6CD5;&#xFF0C;&#x5C06; <code>url</code> &#x4F20;&#x5165;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pushState</span> (<span class="hljs-params">url?: string, replace?: boolean</span>) </span>{
  <span class="hljs-keyword">const</span> history = <span class="hljs-built_in">window</span>.history
  <span class="hljs-keyword">try</span> {
   <span class="hljs-comment">// &#x8C03;&#x7528;&#x6D4F;&#x89C8;&#x5668;&#x539F;&#x751F;&#x7684; history &#x7684; pushState &#x63A5;&#x53E3;&#x6216;&#x8005; replaceState &#x63A5;&#x53E3;,pushState &#x65B9;&#x6CD5;&#x4F1A;&#x5C06; url &#x5165;&#x6808;</span>
    <span class="hljs-keyword">if</span> (replace) {
      history.replaceState({ <span class="hljs-attr">key</span>: _key }, <span class="hljs-string">&apos;&apos;</span>, url)
    } <span class="hljs-keyword">else</span> {
      _key = genKey()
      history.pushState({ <span class="hljs-attr">key</span>: _key }, <span class="hljs-string">&apos;&apos;</span>, url)
    }
  } <span class="hljs-keyword">catch</span> (e) {
    <span class="hljs-built_in">window</span>.location[replace ? <span class="hljs-string">&apos;replace&apos;</span> : <span class="hljs-string">&apos;assign&apos;</span>](url)
  }
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#xFF0C;<code>push</code> &#x5E95;&#x5C42;&#x8C03;&#x7528;&#x4E86;&#x6D4F;&#x89C8;&#x5668;&#x539F;&#x751F;&#x7684; <code>history</code> &#x7684; <code>pushState</code> &#x548C; <code>replaceState</code> &#x65B9;&#x6CD5;&#xFF0C;&#x4E0D;&#x662F; <code>replace</code> &#x6A21;&#x5F0F; &#x4F1A;&#x5C06; url &#x63A8;&#x5386;&#x53F2;&#x6808;&#x5F53;&#x4E2D;&#x3002;</p>
<p><strong>&#x53E6;&#x5916;&#x63D0;&#x4E00;&#x5634;&#x62FC;&#x63A5;&#x54C8;&#x5E0C;&#x7684;&#x539F;&#x7406;</strong></p>
<p>&#x521D;&#x59CB;&#x5316; <code>HashHistory</code> &#x65F6;&#xFF0C;&#x6784;&#x9020;&#x51FD;&#x6570;&#x4F1A;&#x6267;&#x884C; <code>ensureSlash</code> &#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HashHistory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">History</span> </span>{
  <span class="hljs-keyword">constructor</span> (router: Router, base: ?string, fallback: boolean) {
    ...
    ensureSlash()
  }
  ...
  }
</code></pre>
<p>&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x9996;&#x5148;&#x8C03;&#x7528; <code>getHash</code>,&#x7136;&#x540E;&#x6267;&#x884C; <code>replaceHash()</code></p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ensureSlash</span> (<span class="hljs-params"></span>): <span class="hljs-title">boolean</span> </span>{
  <span class="hljs-keyword">const</span> path = getHash()
  <span class="hljs-keyword">if</span> (path.charAt(<span class="hljs-number">0</span>) === <span class="hljs-string">&apos;/&apos;</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
  }
  replaceHash(<span class="hljs-string">&apos;/&apos;</span> + path)
  <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
}
</code></pre>
<p>&#x4E0B;&#x9762;&#x662F;&#x8FD9;&#x51E0;&#x4E2A;&#x65B9;&#x6CD5;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getHash</span> (<span class="hljs-params"></span>): <span class="hljs-title">string</span> </span>{
  <span class="hljs-keyword">const</span> href = <span class="hljs-built_in">window</span>.location.href
  <span class="hljs-keyword">const</span> index = href.indexOf(<span class="hljs-string">&apos;#&apos;</span>)
  <span class="hljs-keyword">return</span> index === <span class="hljs-number">-1</span> ? <span class="hljs-string">&apos;&apos;</span> : href.slice(index + <span class="hljs-number">1</span>)
}
<span class="hljs-comment">// &#x771F;&#x6B63;&#x62FC;&#x63A5;&#x54C8;&#x5E0C;&#x7684;&#x65B9;&#x6CD5; </span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUrl</span> (<span class="hljs-params">path</span>) </span>{
  <span class="hljs-keyword">const</span> href = <span class="hljs-built_in">window</span>.location.href
  <span class="hljs-keyword">const</span> i = href.indexOf(<span class="hljs-string">&apos;#&apos;</span>)
  <span class="hljs-keyword">const</span> base = i &gt;= <span class="hljs-number">0</span> ? href.slice(<span class="hljs-number">0</span>, i) : href
  <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${base}</span>#<span class="hljs-subst">${path}</span>`</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">replaceHash</span> (<span class="hljs-params">path</span>) </span>{
  <span class="hljs-keyword">if</span> (supportsPushState) {
    replaceState(getUrl(path))
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">window</span>.location.replace(getUrl(path))
  }
}
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">replaceState</span> (<span class="hljs-params">url?: string</span>) </span>{
  pushState(url, <span class="hljs-literal">true</span>)
}
</code></pre>
<p>&#x4E3E;&#x4E2A;&#x4F8B;&#x5B50;&#x6765;&#x8BF4;: &#x5047;&#x8BBE;&#x5F53;&#x524D;URL&#x662F; <code>http://localhost:8080</code>,<code>path</code> &#x4E3A;&#x7A7A;&#xFF0C;&#x6267;&#x884C; <code>replcaeHash(&apos;/&apos; + path)</code>,&#x7136;&#x540E;&#x5185;&#x90E8;&#x6267;&#x884C; <code>getUrl</code> &#x8BA1;&#x7B97;&#x51FA; <code>url</code> &#x4E3A;<code>http://localhost:8080/#/</code>,&#x6700;&#x540E;&#x6267;&#x884C; <code>pushState(url,true)</code>&#xFF0C;&#x5C31;&#x5927;&#x529F;&#x544A;&#x6210;&#x4E86;&#xFF01;</p>
<h4 id="&#x5C0F;&#x7ED3;_4"><a name="&#x5C0F;&#x7ED3;_4" class="anchor-navigation-ex-anchor" href="#&#x5C0F;&#x7ED3;_4"><i class="fa fa-link" aria-hidden="true"></i></a>&#x5C0F;&#x7ED3;</h4>
<p><code>hash</code> &#x6A21;&#x5F0F;&#x7684; <code>push</code> &#x65B9;&#x6CD5;&#x4F1A;&#x8C03;&#x7528;&#x8DEF;&#x5F84;&#x5207;&#x6362;&#x65B9;&#x6CD5; <code>transitionTo</code>,&#x63A5;&#x7740;&#x5728;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x4E2D;&#x8C03;&#x7528;<code>pushHash</code>&#x65B9;&#x6CD5;&#xFF0C;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x7684; <code>pushState</code> &#x65B9;&#x6CD5;&#x5E95;&#x5C42;&#x662F;&#x8C03;&#x7528;&#x4E86;&#x6D4F;&#x89C8;&#x5668;&#x539F;&#x751F; <code>history</code> &#x7684;&#x65B9;&#x6CD5;&#x3002;<code>push</code> &#x548C; <code>replace</code> &#x7684;&#x533A;&#x522B;&#x5C31;&#x5728;&#x4E8E;&#x4E00;&#x4E2A;&#x5C06; <code>url</code> &#x63A8;&#x5165;&#x4E86;&#x5386;&#x53F2;&#x6808;&#xFF0C;&#x4E00;&#x4E2A;&#x6CA1;&#x6709;&#xFF0C;&#x6700;&#x76F4;&#x89C2;&#x7684;&#x4F53;&#x73B0;&#x5C31;&#x662F; <code>replace</code> &#x6A21;&#x5F0F;&#x4E0B;&#x6D4F;&#x89C8;&#x5668;&#x70B9;&#x51FB;&#x540E;&#x9000;&#x4E0D;&#x4F1A;&#x56DE;&#x5230;&#x4E0A;&#x4E00;&#x4E2A;&#x8DEF;&#x7531;&#x53BB; ,&#x53E6;&#x4E00;&#x4E2A;&#x5219;&#x53EF;&#x4EE5;&#x3002;</p>
<h3 id="router-view--router-link"><a name="router-view--router-link" class="anchor-navigation-ex-anchor" href="#router-view--router-link"><i class="fa fa-link" aria-hidden="true"></i></a>1.2.7. router-view &amp; router-link</h3>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_161622401_0.png" alt="70"></p>
<p><code>vue-router</code> &#x5728; <code>install</code> &#x65F6;&#x5168;&#x5C40;&#x6CE8;&#x518C;&#x4E86;&#x4E24;&#x4E2A;&#x7EC4;&#x4EF6;&#x4E00;&#x4E2A;&#x662F; <code>router-view</code> &#x4E00;&#x4E2A;&#x662F; <code>router-link</code>&#xFF0C;&#x8FD9;&#x4E24;&#x4E2A;&#x7EC4;&#x4EF6;&#x90FD;&#x662F;&#x5178;&#x578B;&#x7684;&#x51FD;&#x6570;&#x5F0F;&#x7EC4;&#x4EF6;&#x3002;<a href="https://github.com/vuejs/vue-router/tree/dev/src/components" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<h4 id="router-view"><a name="router-view" class="anchor-navigation-ex-anchor" href="#router-view"><i class="fa fa-link" aria-hidden="true"></i></a>router-view</h4>
<p>&#x9996;&#x5148;&#x5728; <code>router</code> &#x7EC4;&#x4EF6;&#x6267;&#x884C; <code>beforeCreate</code> &#x8FD9;&#x4E2A;&#x94A9;&#x5B50;&#x65F6;&#xFF0C;&#x628A; <code>this._route</code> &#x8F6C;&#x4E3A;&#x4E86;&#x54CD;&#x5E94;&#x5F0F;&#x7684;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;</p>
<pre><code class="lang-javascript"> Vue.util.defineReactive(<span class="hljs-keyword">this</span>, <span class="hljs-string">&apos;_route&apos;</span>, <span class="hljs-keyword">this</span>._router.history.current)
</code></pre>
<p>&#x6240;&#x4EE5;&#x8BF4;&#x6BCF;&#x6B21;&#x8DEF;&#x7531;&#x5207;&#x6362;&#x90FD;&#x4F1A;&#x89E6;&#x53D1; <code>router-view</code> &#x91CD;&#x65B0; <code>render</code> &#x4ECE;&#x800C;&#x6E32;&#x67D3;&#x51FA;&#x65B0;&#x7684;&#x89C6;&#x56FE;&#x3002;</p>
<p>&#x6838;&#x5FC3;&#x7684; <code>render</code> &#x51FD;&#x6570;&#x4F5C;&#x7528;&#x8BF7;&#x770B;&#x4EE3;&#x7801;&#x6CE8;&#x91CA;</p>
<pre><code class="lang-javascript">  render (_, { props, children, parent, data }) {
    ...
    <span class="hljs-comment">// &#x901A;&#x8FC7; depth &#x7531; router-view &#x7EC4;&#x4EF6;&#x5411;&#x4E0A;&#x904D;&#x5386;&#x76F4;&#x5230;&#x6839;&#x7EC4;&#x4EF6;&#xFF0C;&#x9047;&#x5230;&#x5176;&#x4ED6;&#x7684; router-view &#x7EC4;&#x4EF6;&#x5219;&#x8DEF;&#x7531;&#x6DF1;&#x5EA6;+1 &#x8FD9;&#x91CC;&#x7684; depth &#x6700;&#x76F4;&#x63A5;&#x7684;&#x4F5C;&#x7528;&#x5C31;&#x662F;&#x5E2E;&#x52A9;&#x627E;&#x5230;&#x5BF9;&#x5E94;&#x7684; record</span>
    <span class="hljs-keyword">let</span> depth = <span class="hljs-number">0</span>
    <span class="hljs-keyword">let</span> inactive = <span class="hljs-literal">false</span>
    <span class="hljs-keyword">while</span> (parent &amp;&amp; parent._routerRoot !== parent) {
      <span class="hljs-comment">// parent.$vnode.data.routerView &#x4E3A; true &#x5219;&#x4EE3;&#x8868;&#x5411;&#x4E0A;&#x5BFB;&#x627E;&#x7684;&#x7EC4;&#x4EF6;&#x4E5F;&#x5B58;&#x5728;&#x5D4C;&#x5957;&#x7684; router-view </span>
      <span class="hljs-keyword">if</span> (parent.$vnode &amp;&amp; parent.$vnode.data.routerView) {
        depth++
      }
      <span class="hljs-keyword">if</span> (parent._inactive) {
        inactive = <span class="hljs-literal">true</span>
      }
      parent = parent.$parent
    }
    data.routerViewDepth = depth
    <span class="hljs-keyword">if</span> (inactive) {
      <span class="hljs-keyword">return</span> h(cache[name], data, children)
    }
   <span class="hljs-comment">// &#x901A;&#x8FC7; matched &#x8BB0;&#x5F55;&#x5BFB;&#x627E;&#x51FA;&#x5BF9;&#x5E94;&#x7684; RouteRecord </span>
    <span class="hljs-keyword">const</span> matched = route.matched[depth]
    <span class="hljs-keyword">if</span> (!matched) {
      cache[name] = <span class="hljs-literal">null</span>
      <span class="hljs-keyword">return</span> h()
    }
 <span class="hljs-comment">// &#x901A;&#x8FC7; RouteRecord &#x627E;&#x5230; component</span>
    <span class="hljs-keyword">const</span> component = cache[name] = matched.components[name]
   <span class="hljs-comment">// &#x5F80;&#x7236;&#x7EC4;&#x4EF6;&#x6CE8;&#x518C; registerRouteInstance &#x65B9;&#x6CD5;</span>
    data.registerRouteInstance = <span class="hljs-function">(<span class="hljs-params">vm, val</span>) =&gt;</span> {     
      <span class="hljs-keyword">const</span> current = matched.instances[name]
      <span class="hljs-keyword">if</span> (
        (val &amp;&amp; current !== vm) ||
        (!val &amp;&amp; current === vm)
      ) {
        matched.instances[name] = val
      }
    }
  <span class="hljs-comment">// &#x6E32;&#x67D3;&#x7EC4;&#x4EF6;</span>
    <span class="hljs-keyword">return</span> h(component, data, children)
  }
</code></pre>
<p>&#x89E6;&#x53D1;&#x66F4;&#x65B0;&#x4E5F;&#x5C31;&#x662F; <code>setter</code> &#x7684;&#x8C03;&#x7528;&#xFF0C;&#x4F4D;&#x4E8E; <code>src/index.js</code>&#xFF0C;&#x5F53;&#x4FEE;&#x6539; <code>_route</code> &#x5C31;&#x4F1A;&#x89E6;&#x53D1;&#x66F4;&#x65B0;&#x3002;</p>
<pre><code class="lang-javascript">history.listen(<span class="hljs-function"><span class="hljs-params">route</span> =&gt;</span> {
  <span class="hljs-keyword">this</span>.apps.forEach(<span class="hljs-function">(<span class="hljs-params">app</span>) =&gt;</span> {
    <span class="hljs-comment">// &#x89E6;&#x53D1; setter</span>
    app._route = route
  })
})
</code></pre>
<h4 id="router-link"><a name="router-link" class="anchor-navigation-ex-anchor" href="#router-link"><i class="fa fa-link" aria-hidden="true"></i></a>router-link</h4>
<p>&#x5206;&#x6790;&#x51E0;&#x4E2A;&#x91CD;&#x8981;&#x7684;&#x90E8;&#x5206;&#xFF1A;</p>
<ul>
<li>&#x8BBE;&#x7F6E; <code>active</code> &#x8DEF;&#x7531;&#x6837;&#x5F0F;</li>
</ul>
<p>router-link<code>&#x4E4B;&#x6240;&#x4EE5;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;</code>router-link-active<code>&#x548C;</code>router-link-exact-active<code>&#x8FD9;&#x4E24;&#x4E2A;</code>class<code>&#x53BB;&#x4FEE;&#x6539;&#x6837;&#x5F0F;&#xFF0C;&#x662F;&#x56E0;&#x4E3A;&#x5728;&#x6267;&#x884C;</code>render<code>&#x51FD;&#x6570;&#x65F6;&#xFF0C;&#x4F1A;&#x6839;&#x636E;&#x5F53;&#x524D;&#x7684;&#x8DEF;&#x7531;&#x72B6;&#x6001;&#xFF0C;&#x7ED9;&#x6E32;&#x67D3;&#x51FA;&#x6765;&#x7684;</code>active<code>&#x5143;&#x7D20;&#x6DFB;&#x52A0;</code>class</p>
<pre><code class="lang-javascript">render (h: <span class="hljs-built_in">Function</span>) {
  ...
  const globalActiveClass = router.options.linkActiveClass
  <span class="hljs-keyword">const</span> globalExactActiveClass = router.options.linkExactActiveClass
  <span class="hljs-comment">// Support global empty active class</span>
  <span class="hljs-keyword">const</span> activeClassFallback = globalActiveClass == <span class="hljs-literal">null</span>
    ? <span class="hljs-string">&apos;router-link-active&apos;</span>
    : globalActiveClass
  <span class="hljs-keyword">const</span> exactActiveClassFallback = globalExactActiveClass == <span class="hljs-literal">null</span>
    ? <span class="hljs-string">&apos;router-link-exact-active&apos;</span>
    : globalExactActiveClass
    ...
}
</code></pre>
<ul>
<li><code>router-link</code> &#x9ED8;&#x8BA4;&#x6E32;&#x67D3;&#x4E3A; <code>a</code> &#x6807;&#x7B7E;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x662F;&#x4F1A;&#x53BB;&#x5411;&#x4E0A;&#x67E5;&#x627E;&#x51FA;&#x7B2C;&#x4E00;&#x4E2A; <code>a</code> &#x6807;&#x7B7E;</li>
</ul>
<pre><code class="lang-javascript"> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.tag === <span class="hljs-string">&apos;a&apos;</span>) {
      data.on = on
      data.attrs = { href }
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// find the first &lt;a&gt; child and apply listener and href</span>
      <span class="hljs-keyword">const</span> a = findAnchor(<span class="hljs-keyword">this</span>.$slots.default)
      <span class="hljs-keyword">if</span> (a) {
        <span class="hljs-comment">// in case the &lt;a&gt; is a static node</span>
        a.isStatic = <span class="hljs-literal">false</span>
        <span class="hljs-keyword">const</span> aData = (a.data = extend({}, a.data))
        aData.on = on
        <span class="hljs-keyword">const</span> aAttrs = (a.data.attrs = extend({}, a.data.attrs))
        aAttrs.href = href
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// &#x4E0D;&#x5B58;&#x5728;&#x5219;&#x6E32;&#x67D3;&#x672C;&#x8EAB;&#x5143;&#x7D20;</span>
        data.on = on
      }
    }
</code></pre>
<ul>
<li>&#x5207;&#x6362;&#x8DEF;&#x7531;&#xFF0C;&#x89E6;&#x53D1;&#x76F8;&#x5E94;&#x4E8B;&#x4EF6;</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handler = <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (guardEvent(e)) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.replace) {
      <span class="hljs-comment">// replace&#x8DEF;&#x7531;</span>
      router.replace(location)
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// push &#x8DEF;&#x7531;</span>
      router.push(location)
    }
  }
}
</code></pre>
<h2 id="&#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x539F;&#x7406;&#x5206;&#x6790;"><a name="&#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x539F;&#x7406;&#x5206;&#x6790;" class="anchor-navigation-ex-anchor" href="#&#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x539F;&#x7406;&#x5206;&#x6790;"><i class="fa fa-link" aria-hidden="true"></i></a>1.3. &#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x539F;&#x7406;&#x5206;&#x6790;</h2>
<p>&#x6211;&#x76F8;&#x4FE1;&#xFF0C;&#x5F00;&#x53D1;&#x8FC7;&#x540E;&#x53F0;&#x9879;&#x76EE;&#x7684;&#x540C;&#x5B66;&#x7ECF;&#x5E38;&#x4F1A;&#x78B0;&#x5230;&#x4EE5;&#x4E0B;&#x7684;&#x573A;&#x666F;: &#x4E00;&#x4E2A;&#x7CFB;&#x7EDF;&#x5206;&#x4E3A;&#x4E0D;&#x540C;&#x7684;&#x89D2;&#x8272;&#xFF0C;&#x7136;&#x540E;&#x4E0D;&#x540C;&#x7684;&#x89D2;&#x8272;&#x5BF9;&#x5E94;&#x4E0D;&#x540C;&#x7684;&#x64CD;&#x4F5C;&#x83DC;&#x5355;&#x548C;&#x64CD;&#x4F5C;&#x6743;&#x9650;&#x3002;&#x4F8B;&#x5982;: &#x6559;&#x5E08;&#x53EF;&#x4EE5;&#x67E5;&#x8BE2;&#x6559;&#x5E08;&#x81EA;&#x5DF1;&#x7684;&#x4E2A;&#x4EBA;&#x4FE1;&#x606F;&#x67E5;&#x8BE2;&#x7136;&#x540E;&#x8FD8;&#x53EF;&#x4EE5;&#x67E5;&#x8BE2;&#x64CD;&#x4F5C;&#x5B66;&#x751F;&#x7684;&#x4FE1;&#x606F;&#x548C;&#x5B66;&#x751F;&#x7684;&#x6210;&#x7EE9;&#x7CFB;&#x7EDF;&#x3001;&#x5B66;&#x751F;&#x7528;&#x6237;&#x53EA;&#x5141;&#x8BB8;&#x67E5;&#x8BE2;&#x4E2A;&#x4EBA;&#x6210;&#x7EE9;&#x548C;&#x4FE1;&#x606F;&#xFF0C;&#x4E0D;&#x5141;&#x8BB8;&#x66F4;&#x6539;&#x3002;&#x5728; <code>vue2.2.0</code> &#x4E4B;&#x524D;&#x8FD8;&#x6CA1;&#x6709;&#x52A0;&#x5165; <code>addRoutes</code> &#x8FD9;&#x4E2A; API &#x662F;&#x5341;&#x5206;&#x56F0;&#x96BE;&#x7684;&#x7684;&#x3002;</p>
<p>&#x76EE;&#x524D;&#x4E3B;&#x6D41;&#x7684;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x63A7;&#x5236;&#x7684;&#x65B9;&#x5F0F;&#x662F;:</p>
<ol>
<li>&#x767B;&#x5F55;&#x65F6;&#x83B7;&#x53D6; <code>token</code> &#x4FDD;&#x5B58;&#x5230;&#x672C;&#x5730;&#xFF0C;&#x63A5;&#x7740;&#x524D;&#x7AEF;&#x4F1A;&#x643A;&#x5E26; <code>token</code> &#x518D;&#x8C03;&#x7528;&#x83B7;&#x53D6;&#x7528;&#x6237;&#x4FE1;&#x606F;&#x7684;&#x63A5;&#x53E3;&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7528;&#x6237;&#x7684;&#x89D2;&#x8272;&#x4FE1;&#x606F;&#x3002;</li>
<li>&#x524D;&#x7AEF;&#x518D;&#x6839;&#x636E;&#x5F53;&#x524D;&#x7684;&#x89D2;&#x8272;&#x8BA1;&#x7B97;&#x51FA;&#x76F8;&#x5E94;&#x7684;&#x8DEF;&#x7531;&#x8868;&#x62FC;&#x63A5;&#x5230;&#x5E38;&#x89C4;&#x8DEF;&#x7531;&#x8868;&#x540E;&#x9762;&#x3002;</li>
</ol>
<h3 id="&#x767B;&#x5F55;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5168;&#x8FC7;&#x7A0B;"><a name="&#x767B;&#x5F55;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5168;&#x8FC7;&#x7A0B;" class="anchor-navigation-ex-anchor" href="#&#x767B;&#x5F55;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5168;&#x8FC7;&#x7A0B;"><i class="fa fa-link" aria-hidden="true"></i></a>1.3.1. &#x767B;&#x5F55;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x5168;&#x8FC7;&#x7A0B;</h3>
<p>&#x4E86;&#x89E3; &#x5982;&#x4F55;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x4E4B;&#x540E;&#xFF0C;&#x4E0B;&#x9762;&#x662F;&#x4E00;&#x5F20;&#x5168;&#x8FC7;&#x7A0B;&#x6D41;&#x7A0B;&#x56FE;</p>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_164633810_0.png" alt="70"></p>
<p>&#x524D;&#x7AEF;&#x5728; <code>beforeEach</code> &#x4E2D;&#x5224;&#x65AD;:</p>
<ul>
<li>&#x7F13;&#x5B58;&#x4E2D;&#x5B58;&#x5728; JWT &#x4EE4;&#x724C;<ul>
<li>&#x8BBF;&#x95EE;<code>/login</code>: &#x91CD;&#x5B9A;&#x5411;&#x5230;&#x9996;&#x9875; <code>/</code></li>
<li>&#x8BBF;&#x95EE;<code>/login</code>&#x4EE5;&#x5916;&#x7684;&#x8DEF;&#x7531;:  &#x9996;&#x6B21;&#x8BBF;&#x95EE;&#xFF0C;&#x83B7;&#x53D6;&#x7528;&#x6237;&#x89D2;&#x8272;&#x4FE1;&#x606F;&#xFF0C;&#x7136;&#x540E;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#xFF0C;&#x7136;&#x540E;&#x8BBF;&#x95EE;&#x4EE5; <code>replace</code> &#x6A21;&#x5F0F;&#x8BBF;&#x95EE; <code>/xxx</code> &#x8DEF;&#x7531;&#x3002;&#x8FD9;&#x79CD;&#x6A21;&#x5F0F;&#x7528;&#x6237;&#x5728;&#x767B;&#x5F55;&#x4E4B;&#x540E;&#x4E0D;&#x4F1A;&#x5728; <code>history</code> &#x5B58;&#x653E;&#x8BB0;&#x5F55;</li>
</ul>
</li>
<li>&#x4E0D;&#x5B58;&#x5728; JWT &#x4EE4;&#x724C;<ul>
<li>&#x8DEF;&#x7531;&#x5728;&#x767D;&#x540D;&#x5355;&#x4E2D;: &#x6B63;&#x5E38;&#x8BBF;&#x95EE; <code>/xxx</code> &#x8DEF;&#x7531;</li>
<li>&#x4E0D;&#x5728;&#x767D;&#x540D;&#x5355;&#x4E2D;: &#x91CD;&#x5B9A;&#x5411;&#x5230; <code>/login</code> &#x9875;&#x9762;</li>
</ul>
</li>
</ul>
<h3 id="&#x7ED3;&#x5408;&#x6846;&#x67B6;&#x6E90;&#x7801;&#x5206;&#x6790;"><a name="&#x7ED3;&#x5408;&#x6846;&#x67B6;&#x6E90;&#x7801;&#x5206;&#x6790;" class="anchor-navigation-ex-anchor" href="#&#x7ED3;&#x5408;&#x6846;&#x67B6;&#x6E90;&#x7801;&#x5206;&#x6790;"><i class="fa fa-link" aria-hidden="true"></i></a>1.3.2. &#x7ED3;&#x5408;&#x6846;&#x67B6;&#x6E90;&#x7801;&#x5206;&#x6790;</h3>
<p>&#x4E0B;&#x9762;&#x7ED3;&#x5408; <code>vue-element-admin</code> &#x7684;&#x6E90;&#x7801;&#x5206;&#x6790;&#x8BE5;&#x6846;&#x67B6;&#x4E2D;&#x5982;&#x4F55;&#x5904;&#x7406;&#x8DEF;&#x7531;&#x903B;&#x8F91;&#x7684;&#x3002;</p>
<h4 id="&#x8DEF;&#x7531;&#x8BBF;&#x95EE;&#x903B;&#x8F91;&#x5206;&#x6790;"><a name="&#x8DEF;&#x7531;&#x8BBF;&#x95EE;&#x903B;&#x8F91;&#x5206;&#x6790;" class="anchor-navigation-ex-anchor" href="#&#x8DEF;&#x7531;&#x8BBF;&#x95EE;&#x903B;&#x8F91;&#x5206;&#x6790;"><i class="fa fa-link" aria-hidden="true"></i></a>&#x8DEF;&#x7531;&#x8BBF;&#x95EE;&#x903B;&#x8F91;&#x5206;&#x6790;</h4>
<p>&#x9996;&#x5148;&#x53EF;&#x4EE5;&#x5B9A;&#x4F4D;&#x5230;&#x548C;&#x5165;&#x53E3;&#x6587;&#x4EF6; <code>main.js</code> &#x540C;&#x7EA7;&#x7684; <code>permission.js</code>, &#x5168;&#x5C40;&#x8DEF;&#x7531;&#x5B88;&#x536B;&#x5904;&#x7406;&#x5C31;&#x5728;&#x6B64;&#x3002;<a href="https://github.com/251205668/student-admin-template/blob/master/src/permission.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> whiteList = [<span class="hljs-string">&apos;/login&apos;</span>, <span class="hljs-string">&apos;/register&apos;</span>] <span class="hljs-comment">// &#x8DEF;&#x7531;&#x767D;&#x540D;&#x5355;&#xFF0C;&#x4E0D;&#x4F1A;&#x91CD;&#x5B9A;&#x5411;</span>
<span class="hljs-comment">// &#x5168;&#x5C40;&#x8DEF;&#x7531;&#x5B88;&#x536B;</span>
router.beforeEach(<span class="hljs-keyword">async</span>(to, <span class="hljs-keyword">from</span>, next) =&gt; {
  NProgress.start() <span class="hljs-comment">//&#x8DEF;&#x7531;&#x52A0;&#x8F7D;&#x8FDB;&#x5EA6;&#x6761;</span>
  <span class="hljs-comment">// &#x8BBE;&#x7F6E; meta &#x6807;&#x9898;</span>
  <span class="hljs-built_in">document</span>.title = getPageTitle(to.meta.title)
  <span class="hljs-comment">// &#x5224;&#x65AD; token &#x662F;&#x5426;&#x5B58;&#x5728;</span>
  <span class="hljs-keyword">const</span> hasToken = getToken()
  <span class="hljs-keyword">if</span> (hasToken) {
    <span class="hljs-keyword">if</span> (to.path === <span class="hljs-string">&apos;/login&apos;</span>) {
      <span class="hljs-comment">// &#x6709; token &#x8DF3;&#x8F6C;&#x9996;&#x9875;</span>
      next({ <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;/&apos;</span> })
      NProgress.done()
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">const</span> hasRoles = store.getters.roles &amp;&amp; store.getters.roles.length &gt; <span class="hljs-number">0</span>
      <span class="hljs-keyword">if</span> (hasRoles) {
        next()
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">try</span> {
          <span class="hljs-comment">// &#x83B7;&#x53D6;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#xFF0C;&#x6DFB;&#x52A0;&#x5230;&#x8DEF;&#x7531;&#x8868;&#x4E2D;</span>
          <span class="hljs-keyword">const</span> { roles } = <span class="hljs-keyword">await</span> store.dispatch(<span class="hljs-string">&apos;user/getInfo&apos;</span>)
          <span class="hljs-keyword">const</span> accessRoutes = <span class="hljs-keyword">await</span> store.dispatch(<span class="hljs-string">&apos;permission/generateRoutes&apos;</span>, roles)
          router.addRoutes(accessRoutes)
          <span class="hljs-comment">//  &#x4F7F;&#x7528; replace &#x8BBF;&#x95EE;&#x8DEF;&#x7531;&#xFF0C;&#x4E0D;&#x4F1A;&#x5728; history &#x4E2D;&#x7559;&#x4E0B;&#x8BB0;&#x5F55;&#xFF0C;&#x767B;&#x5F55;&#x5230; dashbord &#x65F6;&#x56DE;&#x9000;&#x7A7A;&#x767D;&#x9875;&#x9762;</span>
          next({ ...to, <span class="hljs-attr">replace</span>: <span class="hljs-literal">true</span> })
        } <span class="hljs-keyword">catch</span> (error) {
          next(<span class="hljs-string">&apos;/login&apos;</span>)
          NProgress.done()
        }
      }
    }
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// &#x65E0; token</span>
    <span class="hljs-comment">// &#x767D;&#x540D;&#x5355;&#x4E0D;&#x7528;&#x91CD;&#x5B9A;&#x5411; &#x76F4;&#x63A5;&#x8BBF;&#x95EE;</span>
    <span class="hljs-keyword">if</span> (whiteList.indexOf(to.path) !== <span class="hljs-number">-1</span>) {
      next()
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// &#x643A;&#x5E26;&#x53C2;&#x6570;&#x4E3A;&#x91CD;&#x5B9A;&#x5411;&#x5230;&#x524D;&#x5F80;&#x7684;&#x8DEF;&#x5F84;</span>
      next(<span class="hljs-string">`/login?redirect=<span class="hljs-subst">${to.path}</span>`</span>)
      NProgress.done()
    }
  }
})
</code></pre>
<p>&#x8FD9;&#x91CC;&#x7684;&#x4EE3;&#x7801;&#x6211;&#x90FD;&#x6DFB;&#x52A0;&#x4E86;&#x6CE8;&#x91CA;&#x65B9;&#x4FBF;&#x5927;&#x5BB6;&#x597D;&#x53BB;&#x7406;&#x89E3;&#xFF0C;&#x603B;&#x7ED3;&#x4E3A;&#x4E00;&#x53E5;&#x8BDD;&#x5C31;&#x662F;&#x8BBF;&#x95EE;&#x8DEF;&#x7531; <code>/xxx</code>&#xFF0C;&#x9996;&#x5148;&#x9700;&#x8981;&#x6821;&#x9A8C; <code>token</code> &#x662F;&#x5426;&#x5B58;&#x5728;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x5C31;&#x5224;&#x65AD;&#x662F;&#x5426;&#x8BBF;&#x95EE;&#x7684;&#x662F;&#x767B;&#x5F55;&#x8DEF;&#x7531;&#xFF0C;&#x8D70;&#x7684;&#x4E0D;&#x662F;&#x767B;&#x5F55;&#x8DEF;&#x7531;&#x5219;&#x9700;&#x8981;&#x5224;&#x65AD;&#x8BE5;&#x7528;&#x6237;&#x662F;&#x5426;&#x662F;&#x7B2C;&#x4E00;&#x8BBF;&#x95EE;&#x9996;&#x9875;&#xFF0C;&#x7136;&#x540E;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#xFF0C;&#x5982;&#x679C;&#x8D70;&#x7684;&#x662F;&#x767B;&#x5F55;&#x8DEF;&#x7531;&#x5219;&#x76F4;&#x63A5;&#x5B9A;&#x4F4D;&#x5230;&#x9996;&#x9875;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709; <code>token</code> &#x5C31;&#x53BB;&#x68C0;&#x67E5;&#x8DEF;&#x7531;&#x662F;&#x5426;&#x5728;&#x767D;&#x540D;&#x5355;(&#x4EFB;&#x4F55;&#x60C5;&#x51B5;&#x90FD;&#x80FD;&#x8BBF;&#x95EE;&#x7684;&#x8DEF;&#x7531;)&#xFF0C;&#x5728;&#x7684;&#x8BDD;&#x5C31;&#x8BBF;&#x95EE;&#xFF0C;&#x5426;&#x5219;&#x91CD;&#x5B9A;&#x5411;&#x56DE;&#x767B;&#x5F55;&#x9875;&#x9762;&#x3002;</p>
<p>&#x4E0B;&#x9762;&#x662F;&#x7ECF;&#x8FC7;&#x5168;&#x5C40;&#x5B88;&#x536B;&#x540E;&#x8DEF;&#x7531;&#x53D8;&#x5316;&#x7684;&#x622A;&#x56FE;</p>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_165551435_0.png" alt="72"></p>
<h4 id="&#x7ED3;&#x5408;vuex&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;"><a name="&#x7ED3;&#x5408;vuex&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;" class="anchor-navigation-ex-anchor" href="#&#x7ED3;&#x5408;vuex&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;"><i class="fa fa-link" aria-hidden="true"></i></a>&#x7ED3;&#x5408;Vuex&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;</h4>
<p>&#x4E0B;&#x9762;&#x5C31;&#x662F;&#x5206;&#x6790;&#x8FD9;&#x4E00;&#x6B65; <code>const accessRoutes = await store.dispatch(&apos;permission/generateRoutes&apos;, roles)</code> &#x662F;&#x600E;&#x4E48;&#x628A;&#x8DEF;&#x7531;&#x751F;&#x6210;&#x51FA;&#x6765;&#x7684;&#x3002;<a href="https://github.com/251205668/student-admin-template/blob/master/src/store/modules/permission.js" target="_blank">&#x6E90;&#x7801;&#x5730;&#x5740;</a></p>
<p>&#x9996;&#x5148; <code>vue-element-admin</code> &#x4E2D;&#x8DEF;&#x7531;&#x662F;&#x5206;&#x4E3A;&#x4E24;&#x79CD;&#x7684;:</p>
<ul>
<li>constantRoutes: &#x4E0D;&#x9700;&#x8981;&#x6743;&#x9650;&#x5224;&#x65AD;&#x7684;&#x8DEF;&#x7531;</li>
<li>asyncRoutes: &#x9700;&#x8981;&#x52A8;&#x6001;&#x5224;&#x65AD;&#x6743;&#x9650;&#x7684;&#x8DEF;&#x7531;</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-comment">// &#x65E0;&#x9700;&#x6821;&#x9A8C;&#x8EAB;&#x4EFD;&#x8DEF;&#x7531;</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> constantRoutes = [
  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;/login&apos;</span>,
    <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">&apos;@/views/login/index&apos;</span>),
    <span class="hljs-attr">hidden</span>: <span class="hljs-literal">true</span>
  }
  ...
  ],
 <span class="hljs-comment">// &#x9700;&#x8981;&#x6821;&#x9A8C;&#x8EAB;&#x4EFD;&#x8DEF;&#x7531; </span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> asyncRoutes = [
  <span class="hljs-comment">// &#x5B66;&#x751F;&#x89D2;&#x8272;&#x8DEF;&#x7531;</span>
  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;/student&apos;</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">&apos;student&apos;</span>,
    <span class="hljs-attr">component</span>: Layout,
    <span class="hljs-attr">meta</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">&apos;&#x5B66;&#x751F;&#x4FE1;&#x606F;&#x67E5;&#x8BE2;&apos;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&apos;documentation&apos;</span>, <span class="hljs-attr">roles</span>: [<span class="hljs-string">&apos;student&apos;</span>] },
    <span class="hljs-attr">children</span>: [
      {
        <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;info&apos;</span>,
        <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">&apos;@/views/student/info&apos;</span>),
        <span class="hljs-attr">name</span>: <span class="hljs-string">&apos;studentInfo&apos;</span>,
        <span class="hljs-attr">meta</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">&apos;&#x4FE1;&#x606F;&#x67E5;&#x8BE2;&apos;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&apos;form&apos;</span> }
      },
      {
        <span class="hljs-attr">path</span>: <span class="hljs-string">&apos;score&apos;</span>,
        <span class="hljs-attr">component</span>: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">&apos;@/views/student/score&apos;</span>),
        <span class="hljs-attr">name</span>: <span class="hljs-string">&apos;studentScore&apos;</span>,
        <span class="hljs-attr">meta</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">&apos;&#x6210;&#x7EE9;&#x67E5;&#x8BE2;&apos;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&apos;score&apos;</span> }
      }
    ]
  }]
  ...
</code></pre>
<p>&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x7684;&#x6E90;&#x7801;&#x4F4D;&#x4E8E; <code>src/store/modules/permission.js</code> &#x4E2D;&#x7684; <code>generateRoutes</code> &#x65B9;&#x6CD5;&#xFF0C;&#x6E90;&#x7801;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="lang-javascript"> generateRoutes({ commit }, roles) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> {
      <span class="hljs-keyword">let</span> accessedRoutes
      <span class="hljs-keyword">if</span> (roles.includes(<span class="hljs-string">&apos;admin&apos;</span>)) {
        accessedRoutes = asyncRoutes || []
      } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// &#x4E0D;&#x662F; admin &#x53BB;&#x904D;&#x5386;&#x751F;&#x6210;&#x5BF9;&#x5E94;&#x7684;&#x6743;&#x9650;&#x8DEF;&#x7531;&#x8868;</span>
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      <span class="hljs-comment">// vuex &#x4E2D;&#x4FDD;&#x5B58;&#x5F02;&#x6B65;&#x8DEF;&#x7531;&#x548C;&#x5E38;&#x89C4;&#x8DEF;&#x7531;</span>
      commit(<span class="hljs-string">&apos;SET_ROUTES&apos;</span>, accessedRoutes)
      resolve(accessedRoutes)
    })
  }
</code></pre>
<p>&#x4ECE; <code>route.js</code> &#x8BFB;&#x53D6; <code>asyncRoutes</code> &#x548C; <code>constantRoutes</code> &#x4E4B;&#x540E;&#x9996;&#x5148;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x89D2;&#x8272;&#x662F;&#x5426;&#x662F; <code>admin</code>&#xFF0C;&#x662F;&#x7684;&#x8BDD;&#x9ED8;&#x8BA4;&#x8D85;&#x7EA7;&#x7BA1;&#x7406;&#x5458;&#x80FD;&#x591F;&#x8BBF;&#x95EE;&#x6240;&#x6709;&#x7684;&#x8DEF;&#x7531;&#xFF0C;&#x5F53;&#x7136;&#x8FD9;&#x91CC;&#x4E5F;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x5426;&#x5219;&#x53BB;&#x8FC7;&#x6EE4;&#x51FA;&#x8DEF;&#x7531;&#x6743;&#x9650;&#x8DEF;&#x7531;&#x8868;&#xFF0C;&#x7136;&#x540E;&#x4FDD;&#x5B58;&#x5230; <code>Vuex</code> &#x4E2D;&#x3002; &#x6700;&#x540E;&#x5C06;&#x8FC7;&#x6EE4;&#x4E4B;&#x540E;&#x7684; <code>asyncRoutes</code> &#x548C; <code>constantRoutes</code> &#x8FDB;&#x884C;&#x5408;&#x5E76;&#x3002; &#x8FC7;&#x6EE4;&#x6743;&#x9650;&#x8DEF;&#x7531;&#x7684;&#x6E90;&#x7801;&#x5982;&#x4E0B;:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">filterAsyncRoutes</span>(<span class="hljs-params">routes, roles</span>) </span>{
  <span class="hljs-keyword">const</span> res = []
  routes.forEach(<span class="hljs-function"><span class="hljs-params">route</span> =&gt;</span> {
    <span class="hljs-comment">// &#x6D45;&#x62F7;&#x8D1D;</span>
    <span class="hljs-keyword">const</span> tmp = { ...route }
    <span class="hljs-comment">// &#x8FC7;&#x6EE4;&#x51FA;&#x6743;&#x9650;&#x8DEF;&#x7531;</span>
    <span class="hljs-keyword">if</span> (hasPermission(roles, tmp)) {
      <span class="hljs-keyword">if</span> (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })
  <span class="hljs-keyword">return</span> res
}
</code></pre>
<p>&#x9996;&#x5148;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x7A7A;&#x6570;&#x7EC4;&#xFF0C;&#x5BF9;&#x4F20;&#x5165; <code>asyncRoutes</code> &#x8FDB;&#x884C;&#x904D;&#x5386;&#xFF0C;&#x5224;&#x65AD;&#x6BCF;&#x4E2A;&#x8DEF;&#x7531;&#x662F;&#x5426;&#x5177;&#x6709;&#x6743;&#x9650;&#xFF0C;&#x672A;&#x547D;&#x4E2D;&#x7684;&#x6743;&#x9650;&#x8DEF;&#x7531;&#x76F4;&#x63A5;&#x820D;&#x5F03; &#x5224;&#x65AD;&#x6743;&#x9650;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">hasPermission</span>(<span class="hljs-params">roles, route</span>) </span>{
  <span class="hljs-keyword">if</span> (route.meta &amp;&amp; route.meta.roles) {
    <span class="hljs-comment">// roles &#x6709;&#x5BF9;&#x5E94;&#x8DEF;&#x7531;&#x5143;&#x5B9A;&#x4E49;&#x7684; role &#x5C31;&#x8FD4;&#x56DE; true</span>
    <span class="hljs-keyword">return</span> roles.some(<span class="hljs-function"><span class="hljs-params">role</span> =&gt;</span> route.meta.roles.includes(role))
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
  }
}
</code></pre>
<p>&#x63A5;&#x7740;&#x9700;&#x8981;&#x5224;&#x65AD;&#x4E8C;&#x7EA7;&#x8DEF;&#x7531;&#x3001;&#x4E09;&#x7EA7;&#x8DEF;&#x7531;&#x7B49;&#x7B49;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x518D;&#x505A;&#x4E00;&#x5C42;&#x8FED;&#x4EE3;&#x5904;&#x7406;&#xFF0C;&#x6700;&#x540E;&#x5C06;&#x8FC7;&#x6EE4;&#x51FA;&#x6765;&#x7684;&#x8DEF;&#x7531;&#x63A8;&#x8FDB;&#x6570;&#x7EC4;&#x8FD4;&#x56DE;&#x3002;&#x7136;&#x540E;&#x8FFD;&#x52A0;&#x5230; <code>constantRoutes</code> &#x540E;&#x9762;</p>
<pre><code class="lang-javascript"> SET_ROUTES: <span class="hljs-function">(<span class="hljs-params">state, routes</span>) =&gt;</span> {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
</code></pre>
<p><strong>&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x751F;&#x6210;&#x5168;&#x8FC7;&#x7A0B;</strong></p>
<p><img src="https://gitee.com/htzyl/img_bed/raw/master/202105/20210521_172122525_0.png" alt="78"></p>
<h2 id="&#x603B;&#x7ED3;"><a name="&#x603B;&#x7ED3;" class="anchor-navigation-ex-anchor" href="#&#x603B;&#x7ED3;"><i class="fa fa-link" aria-hidden="true"></i></a>1.4. &#x603B;&#x7ED3;</h2>
<ul>
<li><code>vue-router</code> &#x6E90;&#x7801;&#x5206;&#x6790;&#x90E8;&#x5206;<ul>
<li>&#x6CE8;&#x518C;: &#x6267;&#x884C; <code>install</code> &#x65B9;&#x6CD5;&#xFF0C;&#x6CE8;&#x5165;&#x751F;&#x547D;&#x5468;&#x671F;&#x94A9;&#x5B50;&#x521D;&#x59CB;&#x5316;</li>
<li>vueRouter: &#x5F53;&#x7EC4;&#x4EF6;&#x6267;&#x884C; <code>beforeCreate</code> &#x4F20;&#x5165; <code>router</code> &#x5B9E;&#x4F8B;&#x65F6;,&#x6267;&#x884C; <code>init</code> &#x51FD;&#x6570;&#xFF0C;&#x7136;&#x540E;&#x6267;&#x884C; <code>history.transitionTo</code> &#x8DEF;&#x7531;&#x8FC7;&#x6E21;</li>
<li>matcher : &#x6839;&#x636E;&#x4F20;&#x5165;&#x7684; <code>routes</code> &#x914D;&#x7F6E;&#x521B;&#x5EFA;&#x5BF9;&#x5E94;&#x7684; <code>pathMap</code> &#x548C; <code>nameMap</code> ,&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x4F20;&#x5165;&#x7684;&#x4F4D;&#x7F6E;&#x548C;&#x8DEF;&#x5F84;&#x8BA1;&#x7B97;&#x51FA;&#x65B0;&#x7684;&#x4F4D;&#x7F6E;&#x5E76;&#x5339;&#x914D;&#x5BF9;&#x5E94;&#x7684; <code>record</code></li>
<li>&#x8DEF;&#x7531;&#x6A21;&#x5F0F;: &#x8DEF;&#x7531;&#x6A21;&#x5F0F;&#x5728;&#x521D;&#x59CB;&#x5316; <code>vueRouter</code> &#x65F6;&#x5B8C;&#x6210;&#x5339;&#x914D;&#xFF0C;&#x5982;&#x679C;&#x6D4F;&#x89C8;&#x5668;&#x4E0D;&#x652F;&#x6301;&#x5219;&#x4F1A;&#x964D;&#x7EA7;</li>
<li>&#x8DEF;&#x7531; &#x5207;&#x6362;: &#x54C8;&#x5E0C;&#x6A21;&#x5F0F;&#x4E0B;&#x5E95;&#x5C42;&#x4F7F;&#x7528;&#x4E86;&#x6D4F;&#x89C8;&#x5668;&#x539F;&#x751F;&#x7684; <code>pushState</code> &#x548C; <code>replaceState</code> &#x65B9;&#x6CD5;</li>
<li>router-view: &#x8C03;&#x7528;&#x7236;&#x7EC4;&#x4EF6;&#x4E0A;&#x5B58;&#x50A8;&#x7684; <code>$route.match</code> &#x63A7;&#x5236;&#x8DEF;&#x7531;&#x5BF9;&#x5E94;&#x7684;&#x7EC4;&#x4EF6;&#x7684;&#x6E32;&#x67D3;&#x60C5;&#x51B5;&#xFF0C;&#x5E76;&#x4E14;&#x652F;&#x6301;&#x5D4C;&#x5957;&#x3002;</li>
<li>router-link: &#x901A;&#x8FC7; <code>to</code> &#x6765;&#x51B3;&#x5B9A;&#x70B9;&#x51FB;&#x4E8B;&#x4EF6;&#x8DF3;&#x8F6C;&#x7684;&#x76EE;&#x6807;&#x8DEF;&#x7531;&#x7EC4;&#x4EF6;&#xFF0C;&#x5E76;&#x4E14;&#x652F;&#x6301;&#x6E32;&#x67D3;&#x6210;&#x4E0D;&#x540C;&#x7684; <code>tag</code>,&#x8FD8;&#x53EF;&#x4EE5;&#x4FEE;&#x6539;&#x6FC0;&#x6D3B;&#x8DEF;&#x7531;&#x7684;&#x6837;&#x5F0F;&#x3002;</li>
</ul>
</li>
<li>&#x6743;&#x9650;&#x63A7;&#x5236;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#x90E8;&#x5206;<ul>
<li>&#x8DEF;&#x7531;&#x903B;&#x8F91;: &#x5168;&#x5C40;&#x8DEF;&#x7531;&#x62E6;&#x622A;&#xFF0C;&#x4ECE;&#x7F13;&#x5B58;&#x4E2D;&#x83B7;&#x53D6;&#x4EE4;&#x724C;&#xFF0C;&#x5B58;&#x5728;&#x7684;&#x8BDD;&#x5982;&#x679C;&#x9996;&#x6B21;&#x8FDB;&#x5165;&#x8DEF;&#x7531;&#x9700;&#x8981;&#x83B7;&#x53D6;&#x7528;&#x6237;&#x4FE1;&#x606F;&#xFF0C;&#x751F;&#x6210;&#x52A8;&#x6001;&#x8DEF;&#x7531;&#xFF0C;&#x8FD9;&#x91CC;&#x9700;&#x8981;&#x5904;&#x7406; <code>/login</code> &#x7279;&#x6B8A;&#x60C5;&#x51B5;&#xFF0C;&#x4E0D;&#x5B58;&#x5728;&#x5219;&#x5224;&#x65AD;&#x767D;&#x540D;&#x5355;&#x7136;&#x540E;&#x8D70;&#x5BF9;&#x5E94;&#x7684;&#x903B;&#x8F91;</li>
<li>&#x52A8;&#x6001;&#x751F;&#x6210;&#x8DEF;&#x7531;: &#x4F20;&#x5165;&#x9700;&#x8981; <code>router.js</code> &#x5B9A;&#x4E49;&#x7684;&#x4E24;&#x79CD;&#x8DEF;&#x7531;&#x3002;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x8EAB;&#x4EFD;&#x662F;&#x5426;&#x662F;&#x7BA1;&#x7406;&#x5458;&#xFF0C;&#x662F;&#x5219;&#x76F4;&#x63A5;&#x62FC;&#x63A5;&#xFF0C;&#x5426;&#x5219;&#x9700;&#x8981;&#x8FC7;&#x6EE4;&#x51FA;&#x5177;&#x5907;&#x6743;&#x9650;&#x7684;&#x8DEF;&#x7531;&#xFF0C;&#x6700;&#x540E;&#x62FC;&#x63A5;&#x5230;&#x5E38;&#x89C4;&#x8DEF;&#x7531;&#x540E;&#x9762;&#xFF0C;&#x901A;&#x8FC7; <code>addRoutes</code> &#x8FFD;&#x52A0;&#x3002; </li>
</ul>
</li>
</ul>
<footer class="page-footer"><span class="copyright">Copyright &#xA9; zhengyuliang all right reserved&#xFF0C;powered by Gitbook</span><span class="footer-modification">&#x8BE5;&#x6587;&#x4EF6;&#x7F16;&#x5199;&#x65F6;&#x95F4;&#xFF1A;
2021-05-21 18:03:48
</span></footer></body></html>
                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境.html" class="navigation navigation-prev " aria-label="Previous page: 从 0 开始手把手带你搭建一套规范的 Vue3.X 项目工程环境">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="父组件监听到子组件的生命周期.html" class="navigation navigation-next " aria-label="Next page: 父组件监听到子组件的生命周期">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"浅析 Vue Router 源码和动态路由权限分配","level":"3.7","depth":1,"next":{"title":"父组件监听到子组件的生命周期","level":"3.8","depth":1,"path":"Vue/父组件监听到子组件的生命周期.md","ref":"Vue/父组件监听到子组件的生命周期.md","articles":[]},"previous":{"title":"从 0 开始手把手带你搭建一套规范的 Vue3.X 项目工程环境","level":"3.6","depth":1,"path":"Vue/从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境.md","ref":"Vue/从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境.md","articles":[]},"dir":"ltr"},"config":{"plugins":["sectionx","splitter","tbfed-pagefooter","toggle-chapters","theme-comscore","-lunr","-search","search-plus","donate","anchor-navigation-ex","expandable-chapters","chapter-fold","expandable-chapters-small","livereload"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"tbfed-pagefooter":{"copyright":"Copyright &copy zhengyuliang","modify_label":"该文件编写时间：","modify_format":"YYYY-MM-DD HH:mm:ss"},"chapter-fold":{},"pluginsConfig":{"anchor-navigation-ex":{"showLevel":false,"showGoTop":true,"isRewritePageTitle":true,"isShowTocTitleIcon":true,"tocLevel1Icon":"fa fa-hand-o-right","tocLevel2Icon":"fa fa-hand-o-right","tocLevel3Icon":"fa fa-hand-o-right"}},"livereload":{},"splitter":{},"donate":{"title":"","button":"赏","wechat":"https://gitee.com/htzyl/img_bed/raw/master/pay/weixin-min.jpg","alipay":"https://gitee.com/htzyl/img_bed/raw/master/pay/alipay-min.jpg","wechatText":"微信打赏","alipayText":"支付宝打赏"},"fontsettings":{"theme":"white","family":"sans","size":2},"sectionx":{"tag":"b"},"highlight":{},"anchor-navigation-ex":{"showLevel":true,"associatedWithSummary":true,"mode":"float","showGoTop":true,"printLog":false,"multipleH1":true,"float":{"floatIcon":"fa fa-navicon","showLevelIcon":false,"level1Icon":"","level2Icon":"","level3Icon":""},"pageTop":{"showLevelIcon":false,"level1Icon":"","level2Icon":"","level3Icon":""}},"theme-comscore":{},"expandable-chapters-small":{},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false},"toggle-chapters":{},"expandable-chapters":{},"search-plus":{}},"theme":"default","author":"zhengyuliang","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"记录技术文档内容","language":"zh-hans","gitbook":">=3.0.0","description":"记录Gitbook的配置和一些插件的使用","theme-default":{"showLevel":true}},"file":{"path":"Vue/浅析 vue-router 源码和动态路由权限分配.md","mtime":"2021-05-21T10:03:48.118Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2022-01-06T09:44:01.178Z"},"basePath":"..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../gitbook/gitbook.js"></script>
    <script src="../gitbook/theme.js"></script>
    
        
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sectionx/sectionx.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-splitter/splitter.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-toggle-chapters/toggle.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search-plus/jquery.mark.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search-plus/search.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-donate/plugin.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-expandable-chapters/expandable-chapters.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-chapter-fold/chapter-fold.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-livereload/plugin.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-theme-comscore/test.js"></script>
        
    

    </body>
</html>

